java.util.Timer

Java.Util.Timer

Timer

        一种工具,线程用其安排以后在后台线程中执行的任务。可安排任务执行一次,或者定期重复执行。

        与每个Timer对象相对应的是单个后台线程,用于顺序地执行所有计时器任务。计时器任务应该迅速完成。如果完成某个计时器任务的时间太长,那么它会“独占”计时器的任务执行线程。因此,这就可能延迟后续任务的执行,而这些任务就可能“堆在一起”,并且在上述不友好的任务最终完成时才能够被快速连续地执行。

        对Timer对象最后的引用完成后,并且所有未处理的任务都已执行完成后,计时器的任务执行线程会正常终止(并且成为垃圾回收的对象)。但是这可能要很长时间后才发生。默认情况下,任务执行线程并不作为守护线程来运行,所以它能够阻止应用程序终止。如果调用者想要快速终止计时器的任务执行线程,那么调用者应该调用计时器的 cancel方法。

        如果意外终止了计时器的任务执行线程,例如调用了它的stop方法,那么所有以后对该计时器安排任务的尝试都将导致IllegalStateException,就好像调用了计时器的 cancel方法一样。

        此类是线程安全的:多个线程可以共享单个 Timer 对象而无需进行外部同步。

        此类不提供实时保证:它使用 Object.wait(long) 方法来安排任务。

        实现注意事项:此类可扩展到大量同时安排的任务(存在数千个都没有问题)。在内部,它使用二进制堆来表示其任务队列,所以安排任务的开销是 O(log n),其中n是同时安排的任务数。

        实现注意事项:所有构造方法都启动计时器线程。


TimerTask

        由Timer安排为一次执行或重复执行的任务。


Timer接口

package com.zxt.timer;

import java.util.TimerTask;

public interface TimerInterface {
	// true:说明这个timer以daemon方式运行(优先级低,程序结束timer也自动结束)
	// 注意,javax.swing包中也有一个Timer类,如果import中用到swing包,要注意名字的冲突。
	java.util.Timer timer = new java.util.Timer(true);

	TimerTask task = new TimerTask() {   
		public void run() {
			... // 每次需要执行的代码放到这里面。   
		}
	};
	  
	//以下是几种调度task的方法:
	
	// time为Date类型:在指定时间执行一次。
	timer.schedule(task, time);
	
	// firstTime为Date类型,period为long   
	// 从firstTime时刻开始,每隔period毫秒执行一次。
	timer.schedule(task, firstTime, period);
	   
	// delay 为long类型:从现在起过delay毫秒执行一次   
	timer.schedule(task, delay);
	
	// delay为long, period为long:从现在起过delay毫秒以后,每隔period毫秒执行一次。  
	timer.schedule(task, delay, period);
	
	// 安排指定的任务在指定的时间开始进行重复的固定速率执行。
	timer.scheduleAtFixedRate(task, firstTime, period);
    
	// 安排指定的任务在指定的延迟后开始进行重复的固定速率执行。
	timer.scheduleAtFixedRate(task, delay, period);
}


Timer的简单使用

制定任务:

package com.zxt.timer;

public class TimerTaskTest extends java.util.TimerTask {

	@Override
	public void run() {
		System.out.println("start");
	}
}

调用Timer:

package com.zxt.timer;

import java.util.Timer;

public class Test {

	public static void main(String[] args) {
		Timer timer = new Timer();
		// 在1秒后,每隔2秒执行一次程序 
		timer.schedule(new TimerTaskTest(), 1000, 2000);
	}
}


Timer的缺陷

        1、由于执行任务的线程只有一个,所以如果某个任务的执行时间过长,那么将破坏其他任务的定时精确性。如一个任务每1秒执行一次,而另一个任务执行一次需要5秒,那么如果是固定速率的任务,那么会在5秒这个任务执行完成后连续执行5次,而固定延迟的任务将丢失4次执行。

        2、如果执行某个任务过程中抛出了异常,那么执行线程将会终止,导致Timer中的其他任务也不能再执行。

        3、Timer使用的是绝对时间,即是某个时间点,所以它执行依赖系统的时间,如果系统时间修改了的话,将导致任务可能不会被执行。 


更好的替代方法

        由于Timer存在上面说的这些缺陷,在JDK1.5中,我们可以使用ScheduledThreadPoolExecutor来代替它,使用Executors.newScheduledThreadPool工厂方法或使用ScheduledThreadPoolExecutor的构造函数来创建定时任务,它是基于线程池的实现,不会存在Timer存在的上述问题,当线程数量为1时,它相当于Timer。

你可能感兴趣的:(Java多线程,Java类库,JDK_API学习,Java多线程—并发)