我有一些代碼響應PropertyChangeEvent
。這個事件的問題在於它可以連續發射幾次或根本不發射。這個事件是否僅僅被解僱一次或多次是不可預測的,而且我無法控制這個事件是如何被解僱的。我希望事件監聽器只被解僱一次。忽略重複發生的事件
我對這個問題的解決方案是使用我寫的名爲DelayedRunnable
的類。我把聽衆打包在DelayedRunnable
。當事件第一次被觸發時,偵聽器計劃在一秒鐘後執行 - 這是我任意決定的一段時間。隨後的事件發生將被忽略,直到這一秒鐘過去。下面是DelayedRunnable
代碼:
public class DelayedRunnable implements Runnable {
final Runnable runnable;
final int delayAmount;
final TimeUnit delayUnit;
final ScheduledExecutorService service = new ScheduledThreadPoolExecutor(1);
final Runnable executeRunnable = new ExecuteRunnable();
final AtomicBoolean scheduled = new AtomicBoolean(false);
public DelayedRunnable(Runnable runnable, int delayAmount, TimeUnit delayUnit) {
if (runnable == null)
throw new IllegalArgumentException("runnable == null");
this.runnable = runnable;
this.delayAmount = delayAmount;
this.delayUnit = delayUnit;
}
public void run() {
if (!scheduled.compareAndSet(false, true))
return;
service.schedule(executeRunnable, delayAmount, delayUnit);
}
class ExecuteRunnable implements Runnable {
public void run() {
runnable.run();
scheduled.set(false);
}
}
}
當我換聽者DelayedRunnable
,它就會被調用一次。 DelayedRunnable
的一個輔助好處是,偵聽器代碼不會在Swing EDT上執行,因爲偵聽器代碼很昂貴。
但是我發現有時聽者永遠不會被調用,可能是由於DelayedRunnable
中的併發問題。當我重新啓動應用程序時,聽衆再次神奇地工作。正如人們所期望的那樣,由於併發編程的性質,我無法重現DelayedRunnable
無法工作的情況。另外,一秒的時間限制完全是任意的。在某些電腦上,一秒鐘可能不夠。在其他電腦上,一秒鐘太長。沒有簡單的方法來設定時間限制。
我有兩個問題:
有誰知道有
DelayedRunnable
,我無法看到的問題?有沒有比採用這種
DelayedRunnable
方法更好的處理這個問題的方法?
請參閱[應用程序設計問題](http://www.oracle.com/technetwork/articles/javase/index-142890.html#5)。 – trashgod
移動到答案。 – jtahlborn
trashgod,我無法控制事件是如何觸發的。而且,問題不在於事件會被永遠來回發射,而只是事件被不必要地和不可預測地被解僱了一次以上。 –