Java Timer и TimerTask. Теория
Класс java.util.Timer
является служебным и может быть использован для отложенного запуска потока в определенное время. Класс Java Timer может быть использован для запланированной задачи, которая должна будет выполниться один раз или запускаться регулярно в определенное время.
Класс java.util.TimerTask
является абстрактным классом, который реализует интерфейс Runnable. Мы должны унаследоваться от этого класса, создавая наш собственный TimerTask.
- Класс
Timer
является потокобезопасным, поэтому несколько потоков могут совместно использовать один объектTimer
без необходимости внешней синхронизации. - Класс Timer использует
java.util.TaskQueue
для выполнения задач с определенной периодичностью. - В одно и то же время может быть выполнен только один поток TimerTask. Например, если вы создаете Timer, который должен запускаться каждые 10 секунд, но выполнение одного потока занимает целых 20 секунд, то объект Timer будет добавлять задачи в очередь пока один поток не закончит свое выполнение. Как только он отработает свои 20 секунд, то об этом будет уведомлена очередь и следующий поток из этой очереди начнет работать.
Класс Timer использует методы wait()
и notify()
для планирования задач.
Java Timer и TimerTask. Практика
Давайте на примере рассмотрим использование Timer
и TimerTask
в Java:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 |
package ua.com.prologistic; import java.util.Date; import java.util.Timer; import java.util.TimerTask; public class MyTimerTask extends TimerTask { @Override public void run() { System.out.println("TimerTask начал свое выполнение в:" + new Date()); completeTask(); System.out.println("TimerTask закончил свое выполнение в:" + 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(); // стартуем TimerTask в виде демона Timer timer = new Timer(true); // будем запускать каждых 10 секунд (10 * 1000 миллисекунд) timer.scheduleAtFixedRate(timerTask, 0, 10*1000); System.out.println("TimerTask начал выполнение"); // вызываем cancel() через какое-то время try { Thread.sleep(120000); } catch (InterruptedException e) { e.printStackTrace(); } timer.cancel(); System.out.println("TimerTask прекращена"); try { Thread.sleep(30000); } catch (InterruptedException e) { e.printStackTrace(); } } } |
Обратите внимание, что выполнение одного потока будет длиться 20 секунд, а объект Timer запланирован запускаться каждые 10 секунд. Вот результат выполнения программы:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
TimerTask начал выполнение TimerTask начал свое выполнение в:Mon Nov 09 11:23:39 PST 2015 TimerTask закончил свое выполнение в:Mon Nov 09 11:23:59 PST 2015 TimerTask начал свое выполнение в:Mon Nov 09 11:23:59 PST 2015 TimerTask закончил свое выполнение в:Mon Nov 09 11:24:19 PST 2015 TimerTask начал свое выполнение в:Mon Nov 09 11:24:19 PST 2015 TimerTask закончил свое выполнение в:Mon Nov 09 11:24:39 PST 2015 TimerTask начал свое выполнение в:Mon Nov 09 11:24:39 PST 2015 TimerTask закончил свое выполнение в:Mon Nov 09 11:23:59 PST 2015 TimerTask начал свое выполнение в:Mon Nov 09 11:23:59 PST 2015 TimerTask закончил свое выполнение в:Mon Nov 09 11:24:19 PST 2015 TimerTask начал свое выполнение в:Mon Nov 09 11:24:19 PST 2015 TimerTask прекращен TimerTask закончил свое выполнение в:Mon Nov 09 11:24:39 PST 2015 |
Результат выполнения подтверждает, что если задача уже выполняется, то Timer будет ждать её до конца. Когда он закончил одну задачу, то сразу же начнет следующую задачу из очереди.
Метод cancel()
класса Timer используется для завершения выполнения таймера и отказа от дальнейшего выполнения любых запланированных задач. Однако это не мешает ему дать закончить выполнение текущей задачи. Если таймер работает в демона, то будет прекращен, как только все пользовательские потоки закончат свое выполнение.
Класс Таймер содержит несколько методов schedule()
, чтобы запланировать задачу на одноразовое выполнение в указанное время или регулярное выполнение с определенной задержкой. Есть несколько методов scheduleAtFixedRate
()
для периодического запуска задачи с определенным интервалом.
Вот и все, что нужно знать о работе с Java Timer и TimerTask в Java. Следите за обновлениями сайта и разделом Многопоточность в Java.