任務調度(一)——jdk自帶的Timer

       說到任務調度,你們可能會想到Quartz框架,可是jdk自帶的簡單任務調度工具類,反而瞭解的人並非不少。我以爲若是你的業務相對簡單的話,不必非得用Quartz等框架,使用Timer徹底能夠勝任的。簡單來分享一下我瞭解的Timer。java


  Timer是jdk中提供的一個定時器工具,使用的時候會在主線程以外起一個單獨的線程執行指定的計劃任務,能夠指定執行一次或者反覆執行屢次。框架

  TimerTask是一個實現了Runnable接口的抽象類,表明一個能夠被Timer執行的任務。ide


       我是用TimerTask來建立一個任務,其中run方法裏是任務調度的邏輯。使用一個Timer對象來調度任務。工具


       首先給一個特別簡單的示例:測試

package com.tgb.ccl.schema;

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

/** 
 * 不可動態修改的任務
 * 
 * @author arron
 * @date 2015年5月7日 下午1:52:15 
 * @version 1.0 
 */
public class FixedTimerTask extends TimerTask{

	@Override
	public void run() {
		Date d = new Date();
		for(int i=0;i<3;i++){
			try {
				Thread.sleep(1000);
				System.out.println("已執行【"+(i+1)+"】秒鐘,at: "+d.toLocaleString());
			} catch (InterruptedException e) {
				e.printStackTrace();
			}
		}
		System.out.println("本次任務調度結束,at: "+new Date().toLocaleString());
		System.out.println("---------------------------");
	}
	
}

package com.tgb.ccl.schema;

import java.util.Calendar;
import java.util.Date;
import java.util.Timer;

/**
 * 任務調度管理器
 * 
 * @author arron
 * @date 2015年5月7日 下午1:57:19
 * @version 1.0
 */
public class TaskManager {
//	private static final long PERIOD = 5 * 60 * 1000;// 5分鐘
	private static final long PERIOD = 5 * 1000;// 1秒鐘

	public TaskManager() {
		Timer timer = new Timer();
		FixedTimerTask task = new FixedTimerTask();
		System.out.println("start");
		
		
		//0表示當即執行一次,之後每隔一段時間執行一次
		timer.schedule(task, 0, PERIOD);
		
		//1000表示1秒後執行一次,之後每隔一段時間執行一次
		//timer.schedule(task, 1000, PERIOD);
		
		//0表示當即執行一次,之後每隔一段時間執行一次
		//timer.schedule(task, 1000, PERIOD);
		
		// 在當天14點4分整,執行一次,之後再也不執行
		//timer.schedule(task, bookTime(15,0,0));
		
		//在當天14點4分整,執行一次,之後每隔一段時間執行一次
		//若是時間超過了設定時間,會當即執行一次
//		timer.schedule(task, bookTime(0,34,10),PERIOD);
//		timer.scheduleAtFixedRate(task, bookTime(0,40,0),PERIOD);

	}
	

	private Date bookTime(int hour, int minute, int second) {
		Calendar calendar = Calendar.getInstance();
		calendar.set(Calendar.HOUR_OF_DAY, hour);
		calendar.set(Calendar.MINUTE, minute);
		calendar.set(Calendar.SECOND, second);
		Date date = calendar.getTime();
		return date;
	}
	
	public static void main(String[] args) {
		 new TaskManager();
	}
}

       只要執行main方法就能夠測試了。
spa


       你們可能已經注意到了,timer的schedule方法是重載的。參數主要有必須有一個TimerTask實例。第二個參數若是是long類型的,這個參數則是表示延遲時間,以毫秒爲單位。若是爲1000,那就是1秒後執行任務調度。若是是Date類型,則表示設定任務開始執行的時刻。當時間到達這個時刻,那麼任務會自動開始調度。固然若是當前時間已經超過了設定的開始時間,那麼會當即執行一次。第三個參數則是可選參數,是long類型的參數,表示調度的間隔時間。若是有這個參數,表示任務是重複性的調度。不然只會執行一次。這個參數依舊以毫秒爲單位。線程


       若是你稍微注意一下,就會發現timer不僅提供了schedule方法,還提供了scheduleAtFixedRate方法。這兩個方法都是任務調度方法,他們有什麼區別呢?code


       區別在於噹噹前時間已經超過了設定執行時間,schedule方法會當即執行,第二次執行則是按當前執行時間+間隔時間來算的(固然任務執行時間超過了間隔時間,則在第一次執行完畢後,立馬會執行第二次)。而scheduleAtFixedRate方法,一樣是當即執行一次,可是它第二次執行則是按照(當前執行時間-設定的時間)/時間間隔來計算從設定時間到如今還須要執行多少次。
對象


       舉個例子:任務調度須要執行2s,間隔時間是10s,我設定的是8點執行。當前時間爲8點0分10秒,若是是schedule方法,則會當即執行一次,第二次執行時間則是08:00:20。若是是scheduleAtFixedRate方法,則會當即執行一次,而後計算08:00:10-08:00:00整好還能夠執行一次,因此會在08:00:12時,會當即再執行一次,第三次執行則是在08:00:20時執行,之後每隔10s執行一次。接口

   

(左圖是schedule方法的測試效果,右圖是scheduleAtFixedRate方法的測試效果)

       這個跟網上不少人說的不太同樣。不過這個是我測試出來了。他們說的那種結果反正我是測不出來。具體你相信哪一種,你本身試過就清楚了。


       下篇分享一下怎樣動態修改Timer的調度計劃,敬請期待。

相關文章
相關標籤/搜索