Traditional timers use a combination of Timer and TimerTask
java.util.Timer: A timer, which is used to execute a task once after a specified time, or to repeat it periodically.
java.util.TimerTask: inherits the Runnable class, which is essentially a Runnable object
There are two main usage scenarios for Timer and TimerTask timers:
1) After how long, execute the timer task once
2) After how long, execute a timer task, and then execute a task at the same time interval
First, the use of timer
package com.sam; import java.util.Date; import java.util.Timer; import java.util.TimerTask; /** * Review of traditional timers * @author SAM * */ public class TraditionalTimerTask { /** * @param args */ public static void main(String[] args) { Timer timer = new Timer (); timer.scheduleAtFixedRate(new TimerTask() { @Override public void run() { System.out.println("定时器 TName=" + Thread.currentThread().getName() + ",bombing!"); } }, 1000L, 3000L); // For observation, print the current time while (true){ System.out.println(new Date().toLocaleString()); try { Thread.sleep(1000L); } catch (InterruptedException e) { e.printStackTrace (); } } } }
Results of the:
2017-5-13 17:23:30
Timer TName=Timer-0, bombing!
2017-5-13 17:23:32
2017-5-13 17:23:33
2017-5-13 17:23:34
Timer TName=Timer-0, bombing!
2017-5-13 17:23:35
2017-5-13 17:23:36
2017-5-13 17:23:37
Timer TName=Timer-0, bombing!
2017-5-13 17:23:38
2017-5-13 17:23:39
2017-5-13 17:23:40
Timer TName=Timer-0, bombing!
It can be seen that the timer is executed after 1 second for the first time, and the timer task is repeated every 3 seconds after that.
Second, the timer consolidation
Requirement: execute a task after 2 seconds, then execute a task after 4 seconds, and then return to execute a task after 2 seconds,
Then execute the task again in 4 seconds, and so on, please write the code.
package com.sam; import java.util.Date; import java.util.Timer; import java.util.TimerTask; /** * Review of traditional timers * Requirement: execute a task after 2 seconds, then execute a task after 4 seconds, and then return to execute a task after 2 seconds, * Execute a task again in 4 seconds, and so on, please write the code. * @author SAM * */ public class TraditionalTimerTask_2 { /** * @param args */ public static void main(String[] args) { // Execute the scheduled task after 2 seconds new Timer().schedule(new MyTimerTask(), 2000L); // For observation, print the current time while (true){ System.out.println(new Date().toLocaleString()); try { Thread.sleep(1000L); } catch (InterruptedException e) { e.printStackTrace (); } } } } class MyTimerTask extends TimerTask{ static int count; @Override public void run() { // 4 seconds for odd numbers, 2 seconds for even numbers count = ++count % 2; System.out.println("定时器 TName=" + Thread.currentThread().getName() + ",bombing!"); new Timer().schedule(new MyTimerTask(), 2000L + 2000L*count); } }
Results of the:
2017-5-13 17:45:52
2017-5-13 17:45:53
Timer TName=Timer-0, bombing!
2017-5-13 17:45:54
2017-5-13 17:45:55
2017-5-13 17:45:56
2017-5-13 17:45:57
Timer TName=Timer-1, bombing!
2017-5-13 17:45:58
2017-5-13 17:45:59
Timer TName=Timer-2, bombing!
2017-5-13 17:46:00
2017-5-13 17:46:01
2017-5-13 17:46:02
2017-5-13 17:46:03
Timer TName=Timer-3, bombing!
Then go into some details of the Timer class. Timer has two sets of methods for starting timer tasks, which may be confusing:
1)schedule(TimerTask task, long delay, long period)
2)scheduleAtFixedRate(TimerTask task, long delay, long period)
the difference:
他们都可以实现:多长时间后,执行一次定时器任务,之后每间隔相同时间执行一次任务;
但是他们又有一些本质的区别,首先schedule是固定延期执行,而scheduleAtFixedRate是固定速率执行。
再具体说:
1)固定延期,根据前一次执行的实际时间来安排每一次执行。
如果由于任何原因(如垃圾回收或者其他后台活动)而延迟了某次执行,则后续执行也将延迟。
2)固定速率,根据已安排的初始执行时间来安排每次执行。
如果由于任何原因(如垃圾回收或者其他后台活动)而延迟了某次执行,
则将快速连续执行两次或者更多任务,从而使后续执行能够“追赶上来”。
注意这时TimerTask的执行需要考虑同步。
最后推荐一个开源项目,quartz,主要用来实现复杂的调度需求。
例如周一至周五早上10点定时收邮件,周六日不收邮件,
这时使用Timer和TimerTask可能比较复杂,使用quartz开源项目可以很容易的解决这类需求。