美文网首页
Timer源码分析

Timer源码分析

作者: timar | 来源:发表于2018-11-24 15:40 被阅读0次

    Timer是java.util包下jdk自带的一个定时调度类,会在主线程之外另起一个线程来执行所有的定时任务,任务可执行一次,也可以设置间隔,多次执行,任务也可以取消

    delay:第一次执行的延时,为0表示立即执行

    period:执行的时间间隔,为0表示只执行一次

    表示看看Timer类结构

    持有一个TaskQueue,和一个TimerThread的线程,TaskQueue,顾名思义,TimerTask的队列,默认大小 是128,size到128时会扩容,扩大为2倍,而TimerThread负责去执行这些TimerTask

    TimerTask的状态有4种,

    1、VIRGIN:未使用的,即初始状态

    2、SCHEDULED:任务被放到TaskQueue,但是还未执行

    3、EXECUTED:只针对只执行一次的TimerTask,表示已经被执行,或者正准备执行

    4、CANCELLED:被取消

    schedule()方法会将timerTask1加入到timer的任务队列中

    这里会先判断是否需要扩容,可以看到,queue[0]位置上是不会放置任务的

    即queue[1]=task1、queue[2]=task2...

    1、先判断这个TimerTask的状态是否是VIRGIN

    2、设置这个timerTask的状态为SCHEDULEDc

    3、将任务加入到队列中

    4、fixUp,会按执行时间的先后顺序排序,最先执行的放到queue[1]位置上(fixDown的排序也会产生同样效果,即最先执行的放到queue[1]位置上)

    5、如果当前加入的timerTask就是最先执行的,唤醒所有等待queue锁的线程

    第5步唤醒的其实就是TimerThread这个处理所有定时任务的线程,为啥要唤醒?有两个原因

    1、当最开始时,queue队列为空,TimerThread会调用queue.wait(),进入阻塞状态,直到有其它线程调用queue.notify()或者queue.notifyAll(),线程才会从阻塞状态变为执行状态

    2、当queue[1]位置上的timerTask还没有到执行的时间时,会调用queue.wait(executionTime -currentTime),也会阻塞一段时间,而这个时候,如果新加入的timerTask要比现在queue[1]位置上的任务先执行,那么就需要唤醒TimerTask线程

    Timer的构造方法中,就会将TimerThread线程启动

    1、如果队列queue为空,调用queue.wait()进入阻塞状态

    2、queue.getMin(),获取queue[1]位置的timerTask,如果任务状态为CANCELLED,将此任务从队列中移除,再对queue进行排除,将最先执行的timerTask移到到queue[1]位置,

    3、taskFired表示是否已经到了执行时间,如果到了,分两种情况,如果是只执行一次的任务(即period为0),将任务状态state=EXECUTED,并将task从队列中移除,如果是多次执行的任务,刷新这个task的下次执行时间,queue[1].nextExecutionTime =newTime;

    4、如果时间未到,即executionTime > currentTime,调用queue.wait()进入阻塞状态

    5、如果taskFired为true,任务执行

    定时任务的取消

    1、如果是单个任务的取消,调用timerTask.cancel(),

    period为0时,如果状态已经被变更为SCHEDULED,不可被取消,一定会被执行

    2、如果是所有任务的取消,调用timer.cancel();

    newTasksMayBeScheduled为false时,再向队列添加新的任务,会报错

    Timer是一个单线程的定时调用作业,有如下两个缺点

    1、如果前面一个任务执行需要比较长的时候,如10s,那后续任务也只能等待,即使到了queue[2]的执行时间

    2、如果前面一个任务执行时抛出了异常,如RuntimeException,那整个timerThread都会中断,后续任务不会继续执行

    相关文章

      网友评论

          本文标题:Timer源码分析

          本文链接:https://www.haomeiwen.com/subject/zkfyqqtx.html