02_Traditional timer review

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开源项目可以很容易的解决这类需求。

 

 

 

 

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=326322789&siteId=291194637