Пример использования Java Timer и TimerTask

Java java.util.Timer – это утилитарный класс, который можно использовать для планирования выполнения потока в определенное время в будущем. Класс Java Timer можно использовать для планирования задачи на однократное выполнение или для выполнения через определенные интервалы времени.

Java TimerTask

java.util.TimerTask – это абстрактный класс, который реализует интерфейс Runnable, и для создания собственной задачи TimerTask, которая может быть запланирована с помощью класса java Timer, мы должны расширить этот класс.

Пример Java Timer

Класс Java Timer является потокобезопасным, и несколько потоков могут совместно использовать один объект Timer без необходимости во внешней синхронизации. Класс Timer использует java.util.TaskQueue для добавления задач в заданный регулярный интервал, и в любой момент может выполняться только один поток TimerTask. Например, если вы создаете таймер для запуска каждые 10 секунд, но выполнение одним потоком занимает 20 секунд, то объект Timer будет продолжать добавлять задачи в очередь, и как только один поток закончит выполнение, он уведомит очередь, и другой поток начнет выполнение. Класс Java Timer использует методы wait и notify объекта для планирования задач. Вот простая программа для примера использования Java Timer и TimerTask.

package com.journaldev.threads;

import java.util.Date;
import java.util.Timer;
import java.util.TimerTask;

public class MyTimerTask extends TimerTask {

    @Override
    public void run() {
        System.out.println("Timer task started at:"+new Date());
        completeTask();
        System.out.println("Timer task finished at:"+new Date());
    }

    private void completeTask() {
        try {
            // предполагая, что выполнение задачи занимает 20 секунд
            Thread.sleep(20000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }
    
    public static void main(String args[]){
        TimerTask timerTask = new MyTimerTask();
        // запуск задачи таймера как демонов поток
        Timer timer = new Timer(true);
        timer.scheduleAtFixedRate(timerTask, 0, 10*1000);
        System.out.println("TimerTask started");
        // отмена после некоторого времени
        try {
            Thread.sleep(120000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        timer.cancel();
        System.out.println("TimerTask cancelled");
        try {
            Thread.sleep(30000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }

}

Обратите внимание, что выполнение одного потока займет 20 секунд, но объект Java Timer запланирован для выполнения задачи каждые 10 секунд. Вот вывод программы:

TimerTask started
Timer task started at:Wed Dec 26 19:16:39 PST 2012
Timer task finished at:Wed Dec 26 19:16:59 PST 2012
Timer task started at:Wed Dec 26 19:16:59 PST 2012
Timer task finished at:Wed Dec 26 19:17:19 PST 2012
Timer task started at:Wed Dec 26 19:17:19 PST 2012
Timer task finished at:Wed Dec 26 19:17:39 PST 2012
Timer task started at:Wed Dec 26 19:17:39 PST 2012
Timer task finished at:Wed Dec 26 19:17:59 PST 2012
Timer task started at:Wed Dec 26 19:17:59 PST 2012
Timer task finished at:Wed Dec 26 19:18:19 PST 2012
Timer task started at:Wed Dec 26 19:18:19 PST 2012
TimerTask cancelled
Timer task finished at:Wed Dec 26 19:18:39 PST 2012

Выходные данные подтверждают, что если задача уже выполняется, таймер будет ждать ее завершения и после этого снова начнет следующую задачу из очереди. Объект таймера в Java может быть создан для выполнения связанных задач как демонический поток. Метод cancel() таймера используется для завершения таймера и отмены всех запланированных задач, однако он не вмешивается в текущую выполняющуюся задачу и позволяет ей завершиться. Если таймер запущен как демонический поток, то, независимо от того, отменяем мы его или нет, он завершится, как только все пользовательские потоки завершат выполнение. Класс таймера содержит несколько методов schedule() для запланирования задачи на выполнение один раз в указанную дату или после некоторой задержки. Существует несколько методов scheduleAtFixedRate() для запуска задачи периодически с определенным интервалом. При запланировании задач с использованием таймера необходимо убедиться, что интервал времени больше, чем обычное время выполнения потока, иначе размер очереди задач будет продолжать увеличиваться, и в конечном итоге задача будет выполняться постоянно. Это все для краткого обзора Java Timer и Java TimerTask.

Source:
https://www.digitalocean.com/community/tutorials/java-timer-timertask-example