Timer的源码分析

#对java Timer的分析

为什么要分析Timer的源码进行分析?

    希望对Timer类的了解,加深对任务调度的理解。
###Timer源码的分析
public void schedule(TimerTask task, long delay);//经过特定的时间执行
public void schedule(TimerTask task, Date time);//在特定的时间运行
public void schedule(TimerTask task, long delay, long period);//每经过特定的时间再次运行
public void schedule(TimerTask task, Date firstTime, long period);
public void scheduleAtFixedRate(TimerTask task, long delay, long period);//也是经过特定的时间进行运行。

这是Timer的基本用法。
    上面的方法都会调用
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();
    }
}

我们可以看到为了线程安全,首先对queue进行了锁定,然后设置了task下一次的执行时间,以及周期。
那么queue添加task会发生什么事情呢?TaskQueue是一个以执行时间排序的二叉树,距离执行时间最短的越在上面。Timer在初始化的时候会初始化一个TimerThread,并且start它。在run()里面会进行调用mainLoop(),而mainLoop()如下面代码所示:
private void mainLoop() {
while (true) {
try {
TimerTask task;
boolean taskFired;
synchronized(queue) {
// Wait for queue to become non-empty
while (queue.isEmpty() && newTasksMayBeScheduled)
queue.wait();
if (queue.isEmpty())
break; // Queue is empty and will forever remain; die

                // Queue nonempty; look at first evt and do the right thing
                long currentTime, executionTime;
                task = queue.getMin();
                synchronized(task.lock) {
                    if (task.state == TimerTask.CANCELLED) {
                        queue.removeMin();
                        continue;  // No action required, poll queue again
                    }
                    currentTime = System.currentTimeMillis();
                    executionTime = task.nextExecutionTime;
                    if (taskFired = (executionTime<=currentTime)) {
                        if (task.period == 0) { // Non-repeating, remove
                            queue.removeMin();
                            task.state = TimerTask.EXECUTED;
                        } else { // Repeating task, reschedule
                            queue.rescheduleMin(
                              task.period<0 ? currentTime   - task.period
                                            : executionTime + task.period);
                        }
                    }
                }
                if (!taskFired) // Task hasn't yet fired; wait
                    queue.wait(executionTime - currentTime);
            }
            if (taskFired)  // Task fired; run it, holding no locks
                task.run();
        } catch(InterruptedException e) {
        }
    }
}

当获取queue的锁以后,首先我们会判断是否为空,如果为空的话,我们就会等待。然后我们会判断是否到了该执行的时间,如果不是则等待,否则执行。执行的过程中,需要判断是否是否一次性执行的任务,如果是直接从queue中剔除掉,如果不是则需要重新将task添加到queue中,至于为什么需要判断task.period小于0,则是为了区别 public void schedule(TimerTask task, long delay)以及 public void scheduleAtFixedRate(TimerTask task, long delay, long period);这两种任务,AtFixedReate意味着每次都是在特定的时间点执行,与上一次的执行时间无关。而schedule类型的任务下一次的执行时间为本次任务的执行时间点+delay,意味着本次任务的执行与上次的执行有关

注意点:

  

    1. 在某一个Task抛出异常后,那么整个Timer就会停止。
    2. 单个任务会影响别的任务执行
    • 0
      点赞
    • 0
      收藏
      觉得还不错? 一键收藏
    • 0
      评论
    评论
    添加红包

    请填写红包祝福语或标题

    红包个数最小为10个

    红包金额最低5元

    当前余额3.43前往充值 >
    需支付:10.00
    成就一亿技术人!
    领取后你会自动成为博主和红包主的粉丝 规则
    hope_wisdom
    发出的红包
    实付
    使用余额支付
    点击重新获取
    扫码支付
    钱包余额 0

    抵扣说明:

    1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
    2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

    余额充值