У меня есть код, который отвечает на 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
подхода?