Timer
JDK中的Timer 是一个非常早期的类,在1.2中就引入了。现在看来,不算一个很好的设计。
Timer timer = new Timer();
timer.schedule(new MyTimerTask(),1000,10);
其中MyTimerTask 是一个实现TimerTask的类,主要是实现run 方法。
Timer中有2个核心类,一个是Timer,一个TimerTask
前者主要是定义定时任务什么时候执行,后者主要是定义具体定时任务。
Timer
public class Timer {
private final TaskQueue queue = new TaskQueue();
private final TimerThread thread = new TimerThread(queue);
}
其中TaskQueue 是使用数组实现的一个简易的堆,另外一个值得注意的属性是 TimerThread
Timer使用唯一的线程负责轮询并执行任务。Timer的优点在于简单易用,但也因为所有任务都是由同一个线程来调度,因此整个过程是串行执行的,同一时间只能有一个任务在执行,所以在任务量多的情况下不方便使用。
1.Timer 只能被单线程调度
2.TimerTask 中出现的异常会影响到Timer 的执行
由于这两点缺陷,JDK1.5 支持了新的定时器方案 ScheduledExecutorService。
ScheduledExecutorService
public static void main(String[] args) {
ScheduledExecutorService scheduledExecutorService =
Executors.newScheduledThreadPool(10);
scheduledExecutorService.scheduleAtFixedRate(new Runnable() {
@Override
public void run() {
System.out.println("schedualed executor service");
}
},1, 1, TimeUnit.SECONDS);
}
相比Timer,ScheduledExecutorService 解决了同一个定时器调度多个任务的阻塞问题,并且任务异常不会中断 ScheduledExecutorService。
ScheduledExecutorService 提供了2种常用的周期调度方法 ScheduleAtFixedRate 和 ScheduleWithFixedDelay。
ScheduleAtFixedRate 基于固定时间间隔进行任务调度,ScheduleWithFixedDelay 取决于每次任务执行的时间长短,是基于不固定时间间隔的任务调度。
ScheduledExecutorService 底层使用的数据结构为 PriorityQueue。