Таймер Java ScheduleAtFixedRate. Как сделать так, чтобы вызов .cancel останавливал таймер только после выполнения текущей итерации

У меня есть ReentrantReadWriteLock в моем приложении. В методе запуска задачи таймера я пишу блокировку, а затем вызываю функцию. После этого я разблокирую:

timer.scheduleAtFixedRate(new TimerTask() {
                public void run() {
                    lock.writeLock().lock();
                    function();
                    lock.writeLock().unlock();
                }
        }, 0, 1000); // prints 1 every 1second

Меня беспокоит то, что произойдет, если этот таймер будет отменен, и замок не сможет открыться. Есть ли способ сделать так, чтобы вызов .cancel останавливал таймер только после выполнения текущей итерации.

Или есть другая структура данных, которую я мог бы использовать, которая позволяет мне в отдельном потоке запускать задачу/функцию с определенной скоростью и иметь возможность остановить ее, чтобы снять все блокировки?


person LTM    schedule 27.11.2019    source источник
comment
Поведение cancel должно быть таким, как вы ожидали, прочитайте документ Java   -  person samabcde    schedule 27.11.2019


Ответы (1)


В javadoc сообщается, что вызов cancel() не прерывает выполнение текущей задачи, так что в этой части вы в безопасности.

Тем не менее, я рекомендую вам использовать ScheduledThreadPoolExecutor вместо Timer, если вы можете. Он более мощный, простой в использовании и более устойчивый к возможным исключениям, создаваемым запланированными задачами.

С помощью ScheduledThreadPoolExecutor вы можете отменить конкретную задачу, вызвав cancel(boolean mayInterruptIfRunning) для Future, возвращенного при планировании задачи, или отменить все запланированные задачи, завершив работу планировщика (см. методы shutdown + awaitTermination). Если вам нужен только один поток, работающий над задачами, вы можете сделать это.

Я также настоятельно рекомендую заключать получение и освобождение блокировки в блок try...finally. Это гарантирует, что всякий раз, когда внутри задачи возникает проблема, блокировка всегда будет снята должным образом. В противном случае, как вы хорошо заметили, проблема в задаче не позволит снять блокировку.

person QuentinC    schedule 27.11.2019