整理:java定時器。

weixin_33816946發表於2014-05-10

本文純屬個人思路,如有錯誤,請指正。

 

java的Timer依賴Thread,每一個Timer實際上都是一個Thread。

 

import java.util.TimerTask;

/**
 * 本類僅為實現TimerTask,意義不大。
 * @author 9082046**@qq.com
 *
 */
public class Task  extends TimerTask
{	
	public void run() 
	{
		System.out.println(this.hashCode());		
	}
}

 

  在win7 的myeclipse8.5的預設安裝後的未做任何調節的開發環境下:

方案一:

import java.util.Timer;

/**
* 啟動1w個Timer * @author 9082046**@qq.com * */ public class TestTimer { public static void main(String[] args) { add(10000); } public static void add(int amount) { for(int index=0;index < amount; index ++) { Timer timer=new Timer(); timer.schedule(new Task(), Integer.MAX_VALUE); } } }

啟動1w個的Timer,結果如下:

才1w個Timer提示jvm的記憶體不夠使的了。

 

方案二:

/**
 * 
 */
package linked_array;

import java.util.Random;
import java.util.Timer;

/**
 * @author 908204694@qq.com
 *
 */
public class TestTimer 
{	
	public static void main(String[] args)
	{
		add(10000);
	}
	public static void add(int amount)
	{		
		Timer timer=new Timer();
		for(int index=0;index < amount; index ++)
		{			
			timer.schedule(new Task(), Integer.MAX_VALUE);
		}
	}
}

 同一個Timer排程1w個TimerTask,至少在執行5分鐘後沒出什麼Error。。。。貌似有點囧,也沒任何輸出,寫的Timer排程TimerTask的延遲時間有點大,哈。

 在實際應用中,Timer存在計時器執行緒終止 或者 計時器取消 導致的 IllegalStateException,單個Timer 或許不太適合長時間 排程 非重複事件 TimerTask。

原因:對 Timer 物件最後的引用完成後,並且 所有未處理的任務都已執行完成後,計時器的任務執行執行緒會正常終止(並且成為垃圾回收的物件)。但是這可能要很長時間後才發生。出自:jdk api 1.6.0 java.util  類 Timer。

 

方案三:

 

/**
 * @author 9082046**@qq.com
 *
 */
public class User 
{
	private int user_id;
	// 用來標識時間
	private int time_stamp;
	public User(int userId, int timeStamp) 
	{
		user_id = userId;		
		time_stamp = timeStamp;
	}
	
	public int getUser_id() 
	{
		return user_id;
	}
		
	public int getTime_stamp() 
	{
		return time_stamp;
	}

	public void setTime_stamp(int timeStamp) 
	{
		time_stamp = timeStamp;
	}	
}


/**
 * @author 9082046**@qq.com
 *
 */
public class Test_Timer 
{

	private static ArrayList<User> list=new ArrayList<User>();	
	private static Random randam=new Random();
	
	// 計時用,每秒加一。或者直接用時間戳吧。
	private static int timeS = 0;	
	private static final int tenS = 10;
	
	public static void main(String[] args)
	{
		add(10000);
		
		while(true)
		{
			try 
			{
				Thread.sleep(1000);
			}
			catch (InterruptedException e) 
			{
				
			}			
			traveral();
			timeS++;
		}		
	}

		public static void add(int amount)
		{
			for(int index=0;index < amount; index ++)
			{
				int random = randam.nextInt(1000);
				User user =new User(index,random);			
				list.add(user );
			}
		}
		
		/**
		 * 遍歷全部的玩家。
		 */
		public static void traveral()
		{
			int amount=list.size();
			User user = null;
			for(int index=0;index < amount; index ++)
			{		
				user = list.get(index);
				if(user.getTime_stamp() < timeS)
				{
					System.out.println("userId:"+user.getUser_id() +"," +user.getTime_stamp());
					user.setTime_stamp(user.getTime_stamp()+tenS);
				}
			}
		}
}

 

使用Thread.sleep() + 遍歷全部資料實體並比較時間標記位   :模擬計時器。

 

 

 

個人注:

①、 主動讓系統回收垃圾物件:System.gc()。

②、方案二 和 方案三 都存在缺陷, 如果存在長耗時的任務,會導致後續的部分任務 晚於預設的時間標識點才能執行。

 

 

 

 

 

 

 

 

 

 

 

 

 

 

相關文章