Это выглядит как проблема:
private boolean startTimer() {
// ......
if (_TimerFuture != null) {
_TimerFuture.cancel(false);
}
_TimerFuture = _Timer.schedule(new TimerPopTask(),
TIMER_IN_SECONDS,
TimeUnit.SECONDS);
// ......
}
Поскольку вы передаете ложное значение для отмены, старый _TimerFuture
может не быть отменен, если задача уже запущена.В любом случае создается новый (но он не будет работать одновременно, потому что ваш ExecutorService
имеет фиксированный размер пула потоков 1).В любом случае, это не похоже на ваше желаемое поведение перезапуска таймера при вызове startTimer ().
Я бы немного пересмотрел архитектуру.Я бы сделал экземпляр TimerPopTask
тем, что вы «отменили», и я бы оставил ScheduledFutures
один, как только они были созданы:
private class TimerPopTask implements Runnable {
//volatile for thread-safety
private volatile boolean isActive = true;
public void run () {
if (isActive){
TimerPopped();
}
}
public void deactivate(){
isActive = false;
}
}
, тогда я бы скорее сохранил экземпляр TimerPopTask
чем экземпляр ScheduledFuture
и переставить метод startTimer таким образом:
private TimerPopTask timerPopTask;
private boolean startTimer() {
try {
if (timerPopTask != null) {
timerPopTask.deactivate();
}
timerPopTask = new TimerPopTask();
_Timer.schedule(timerPopTask,
TIMER_IN_SECONDS,
TimeUnit.SECONDS);
return true;
} catch (Exception e) {
return false;
}
}
(аналогично модификации метода stopTimer ().)
Возможно, вы захотите увеличить количество потоков, если выискренне ожидаем необходимости «перезапустить» таймер до истечения текущего таймера:
private ScheduledExecutorService _Timer = Executors.newScheduledThreadPool(5);
Возможно, вы захотите использовать гибридный подход, сохраняя ссылки как на текущий TimerPopTask, как я описал, так и на текущий ScheduledFutureи сделайте все возможное, чтобы отменить его и освободить поток, если это возможно, понимая, что отмена отменять не гарантируется.
(Примечание: все это предполагает, что вызовы методов startTimer () и stopTimer () ограничены однимосновной поток, и только потоки TimerPopTask
совместно используются потоками. В противном случае вам потребуются дополнительные меры защиты.)