1. 程式人生 > >java定時器Timer的應用

java定時器Timer的應用

java內部定時任務用的類:import java.util.Timer,import java.util.TimerTask;。、

在執行一些簡單的延時任務時,使用java內部的定時任務比quartz要簡單,用起來方便快捷,當然,如果需要比較複雜的定時任務,比如動態管理、比較複雜的指定時間、多工執行等,還是需要用上quartz,此處就Java內部定時任務的應用作簡要介紹,不作深入分析。

場景介紹:

在web的service執行某一資料庫操作後,需要指定時間後對指定的實體類資料進行操作。

思路:

service執行操作的最後,建立一個定時任務,並把實體類的id傳給定時任務類的方法,用以在執行時獲取該實體類(注:不能將實體類的物件傳進去,執行時會報空指標錯誤,因為此時實體類物件已經為null)。

下面上程式碼:

首先是model層的實體類:

package com.xmty.testmd5;

import java.util.Date;

/**
 * 被定時任務操作的實體類
 * 
 * @author snow
 *
 */
public class ExecuteModel {

	// 實體類id
	String id;
	// 執行時間
	Date executeTime;

	public String getId() {
		return id;
	}

	public void setId(String id) {
		this.id = id;
	}

	public Date getExecuteTime() {
		return executeTime;
	}

	public void setExecuteTime(Date executeTime) {
		this.executeTime = executeTime;
	}

}


下面是呼叫任務的service層類:

package com.xmty.testmd5;

import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;

import com.xmty.util.MyTimeTask;
/**
 * 建立定時任務的類
 * 相當於service層的類
 * @author snow
 *
 */
public class TestTime {

	public static void main(String[] args) {
		ExecuteModel model = new ExecuteModel();
		String id = "aaa";
		Date executeTime = null;
		SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
		try {
			executeTime = format.parse("2017-03-11 21:34:50");
		} catch (ParseException e) {
			e.printStackTrace();
		}
		model.setId(id);
		model.setExecuteTime(executeTime);
		
		//建立一個定時任務
		new MyTimeTask().noticeLost(id, executeTime);
	}
}
下面是執行定時任務的工具類:、
package com.xmty.util;

import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Timer;
import java.util.TimerTask;

import com.xmty.testmd5.ExecuteModel;

/**
 * 執行定時任務的類
 * @author snow
 *
 */
public class MyTimeTask {
	/**
	 * dao層訪問介面
	 * 可以根據executeModel的id通過dao從資料庫中取出
	 * 進行資料庫資料的定時操作
	 */
	/*IDao dao = (IDao) SpringApplicationContextHolder
			.getSpringBean("dao");*/
	
	//定時物件(java工具類)
	Timer timer = new Timer();
	
	//定時任務內部類
	class Item extends TimerTask{
		
		//執行時間
		Date executeTime;
		//被操作實體類id
		//用來從資料庫取出實體類
		String id;

		//構造方法
		Item(String id, Date executeTime){
			this.id = id;
			this.executeTime = executeTime;
		}
		public void run() {
			try {
				operate(id, executeTime);
			} catch (ParseException e) {
				e.printStackTrace();
			}
		}		
	}
	
	//定時任務執行的類,執行時notice已經為null,傳遞
	public void operate(String id, Date executeTime) throws ParseException{
//		ExecuteModel model = dao.getById(id);
//		if (executeTime.getTime() == model.getExecuteTime().getTime()) {
			System.out.println("執行了定時方法 " + executeTime);
			//若只執行一次,則呼叫timer.cancel()取消定時任務
			timer.cancel();
//		}
	}
	
	public void noticeLost(String id, Date executeTime){
		//建立定時任務
		Item item = new Item(id, executeTime);
		//啟動定時任務
		timer.schedule(item,executeTime);
	}
	
}


測試時執行結果如下圖:


由於在執行後呼叫了timer.cancel()方法,取消了當前的定時任務,所以程式自動結束,實現了一次性定時任務的功能。

注:一個timer對應一個單獨的執行緒,這種定時任務是執行緒安全的,定時任務不需要了,最好呼叫timer.cancel()方法將執行緒結束。