java定时器Timer基本原理

Timer总结

Timer是jdk自带的定时器,可以实现单机基本的定时任务, 从指定时间开始,每隔一段时间固定执行等等;它主要具有以下特性

1.单线程同步处理所有任务(TimerTask), 所以任务真正执行的时间点可能和预定的有延迟(因为有可能被前面的任务给耽误了)

2.只要有任务在执行时抛出了异常(InterruptedException除外的所有异常),整个Timer被停止,所有任务也被停止;

3.任务队列基于优先队列,二叉堆来实现的,以保证任务总体上的有序执行

Timer两个重要的成员变量

TimerThread实例对象,实现主循环,选择一个最近要执行的任务进行执行

TaskQueue实例对象,实现了任务队列, 内部实现是优先队列的数据结构

private final TaskQueuequeue =new TaskQueue();

private final TimerThreadthread =new TimerThread(queue);

Timer初始化

通过构造函数在实例化的时候即启动内部线程类TimerThread

public Timer(String name, boolean isDaemon) {

    thread.setName(name);

    thread.setDaemon(isDaemon);

    thread.start();

TimerThread线程启动后调用 mainLoop 一直尝试从优先队列里获取任务(最先待执行的任务)

当队列为空时主循环就一直wait();

当队列不为空时,取队头的任务(即堆顶)并比较任务的执行时间nextExecutionTime与当前时间currentTime,如果时间未到则需要阻塞等待 queue.wait(executionTime - currentTime);

class TimerThreadextends Thread {

    private TaskQueuequeue;

    TimerThread(TaskQueue queue) {

       this.queue = queue;

    }

public void run() {

     try {

          mainLoop();

        }finally {

            。。。

      }

}

/**

* The main timer loop.  (See class comment.)

*/

private void mainLoop() {

   while (true) {

     try {

     ....主循环,一直尝试获取任务...

         if (!taskFired) queue.wait(executionTime - currentTime);

     .......

         if (taskFired) task.run();

     }catch(InterruptedException e) {

    }

}

Timer添加任务

添加的任务都是TimerTask的子类,类似schedule(TimerTask xxx), 即往TaskQueue队列里添加任务, 当发现队列里面刚刚没有数据时则进行notify, 以便唤醒TimerThread继续执行; 见加粗代码部分

添加任务操作最终都会调用 private void sched(TimerTask task, long time, long period)

private void sched(TimerTask task, long time, long period) {

if (time <0)

throw new IllegalArgumentException("Illegal execution time.");

    // Constrain value of period sufficiently to prevent numeric

// overflow while still being effectively infinitely large.

    if (Math.abs(period) > (Long.MAX_VALUE >>1))

period >>=1;

    synchronized(queue) {

if (!thread.newTasksMayBeScheduled)

throw new IllegalStateException("Timer already cancelled.");

        synchronized(task.lock) {

if (task.state != TimerTask.VIRGIN)

throw new IllegalStateException(

"Task already scheduled or cancelled");

            task.nextExecutionTime = time;

            task.period = period;

            task.state = TimerTask.SCHEDULED;

        }

queue.add(task);

        if (queue.getMin() == task)

queue.notify();

    }

}

你可能感兴趣的:(java定时器Timer基本原理)