整理:java定时器。

本文纯属个人思路,如有错误,请指正。

 

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 [email protected]

 *

 */

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()。

②、方案二 和 方案三 都存在缺陷, 如果存在长耗时的任务,会导致后续的部分任务 晚于预设的时间标识点才能执行。

 

 

 

 

 

 

 

 

 

 

 

 

 

 

你可能感兴趣的:(java)