Java Timer详解

Java 的Timer主要由Timer,TaskQueue,TimerThread,TimerTask组成,下面分别讲解,大家想弄懂的话就打开Timer的类,按照我的思路一步一步来吧。
首先是TimerTask,TimerTask继承自Runable,代表一个任务对象,当一个TimerTask 对象 task被一个Timer对象开始调度的时候,task.state = SCHEDULED;注意这个state变量不是public的,是package的,也没有setter方法,只有一个cancel方法,所以不能外部调用,是由Timer内部修改的。这里有一个很重要的一点,就是一旦一个TimerTask对象被调度了以后,不论是否被执行,或是取消,都不能重复使用了,原因也是因为TimerTask对象的state!=VIRGIN。
接下来是TaskQueue,TaskQueue是Timer的内部类,代表一个任务队列,一个Timer对象有一个任务队列,负责存储所有被Timer对象调度的TimerTask。这里有2点比较重要,1是TaskQueue内部用一个数组存储TimerTask,当TimerTask对象个数超过数组长度时,将从新分配一个更大的数组,并将所有TimerTask对象复制到新的数组里,但是当TimerTask对象又变少时,并不会减少数组长度。2是TaskQueue的任务数组采用平衡二叉堆排序,也就是是说queue[n]的左右孩子是queue[2*n]和queue[2*n+1],而且父节点的执行时间<=子节点的执行时间,这样,queue[1]的Timertask对象一定是最快执行的任务,而且在queue里添加,删除,重新调度Timertask的复杂度是log[n]。
接下来是TimerThread,TimerThread继承自Thread,也是Timer的内部类,同时也是Timer里最重要的一部分,TimerThread对象里有一个TaskQueue对象,也就是上面的TaskQueue对象的引用。TimerThread的作用就是不停地从TaskQueue里取出要执行的TimerTask执行,同时监听Timer对象是不是被取消了,如果取消了,则执行完当前任务后就退出(如果当前有任务在执行的话)。
最后是Timer,其实说了TaskQueue和TimerThread之后Timer也说得差不多了,每一个Timer对象有一个TaskQueue对象和一个TimerThread对象,对Timer的所有操作最后也都转化成对这两个对象的操作。这里要说的一点是Timer有两种调度方式,分别是schedule()和scheduleFixedRate(),区别是使用schedule()调度的任务下一次的调度时间是上一次任务被执行的时间加上周期,而使用scheduleFixedRate()调度的任务下一次的调度时间是上一次的调度的时间加上周期,这里的执行时间和调度时间有可能不同,原因就在于如果在某个TimerTask里执行了耗时任务,导致接下来的TimerTask的执行时间都被延迟了,这时候有可能导致一个任务执行时执行时间大于应调度时间,这时候如果是用schedule()调度的则下一次调度时间为当前执行时间加上周期,而如果是用scheduleFixedRate()调度的则下一次调度时间为上一次调度时间加上周期。你去看源码会发现,使用schedule()和scheduleFixedRate()都会转到sched()上只不过schedule()对应的period是负的,scheduleFixedRate()对应的period是正的,sched()里也是根据period的正负来判断进而进行调度的。

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值