Java定时器之Timer源码剖析
2017-08-23 00:00
417 查看
Timer类中有两个主要的引用:
TaskQueue:任务队列
TimerThread:真正执行任务的线程
Timer:任务定时的调度
将元素添加到队列,调整堆。其实是一个堆。
这个TaskQueue是根据nextExecutionTime下一次执行的时间排序的。(调整堆)
什么是堆?像如下的方式,如果不懂的话,自己百度。
注意:TaskQueue这个类很简单,就是一个任务队列,按下一个任务执行的时间建立的一个堆。
TimerThread线程启动之后,就是一直死循环去获取队列的任务
注意:上面在判断到达执行任务的时间之后,再判断是否要重复执行,如果要重复执行的话,重新计算了两个任务的时间间隔:
代码:
task.period<0 ? currentTime - task.period : executionTime + task.period
分析:
period<0代表是上一个任务执行的时间长,超过了设置的前面设置的时间,
下面举个例子:
任务A --9s--- 任务B --9s-- 任务C (注意:9s是我们的设置的任务执行间隔时间)。
但是执行了10s的话,下一个任务相当于延迟了1s,那就currentTime - task.period设置延迟的时间执行。否则正常执行(executionTime + task.period)。
任务规划器:
这里的执行的线程是具体的你代码中哪个线程调用的schedule方法。在我写的代码里由于我是在main方法中直接写的话,这里的是主线程中执行的。
下面是我看完源码之后的理解:
1、一个Timer可以看做一个线程在调度任务。这样有一定的缺点是下一个任务必须等待下一个任务的执行。可以看做任务的串行执行。也就是可以看做同步。如果要是任务执行的时间与设置的时间间隔不冲突的话,这个不是问题。
2、TimerThread线程循环的在干活,不会退出。必须我们手动调用timer.cancel()方法才会退出。这就涉及到了TimerThread与其它线程通信的问题了,比如主线程,也是它的父线程。一般此时的可能退出了,这样的话,没有线程跟TimerThread通信,那它就会成功一个无用的线程。类似于Linux中的“僵尸进程”,线程资源没办法回收。就算它的父线程不退出的话,也办法释放线程资源,因为TimerThread完全封装到了Timer里面,它干完了活没办法通知父线程,父线程自然不会调用timer.cancel()。
Timer#cancel代码如下:
TaskQueue:任务队列
TimerThread:真正执行任务的线程
Timer:任务定时的调度
一、TaskQueue:任务队列
采用数组实现队列:将元素添加到队列,调整堆。其实是一个堆。
这个TaskQueue是根据nextExecutionTime下一次执行的时间排序的。(调整堆)
什么是堆?像如下的方式,如果不懂的话,自己百度。
注意:TaskQueue这个类很简单,就是一个任务队列,按下一个任务执行的时间建立的一个堆。
二、TimerThread:具体执行任务的线程
TimerThread是继承Thread类,然后再run方法中调用mainLoop(),下面就介绍TimerThread类。TimerThread线程启动之后,就是一直死循环去获取队列的任务
注意:上面在判断到达执行任务的时间之后,再判断是否要重复执行,如果要重复执行的话,重新计算了两个任务的时间间隔:
代码:
task.period<0 ? currentTime - task.period : executionTime + task.period
分析:
period<0代表是上一个任务执行的时间长,超过了设置的前面设置的时间,
下面举个例子:
任务A --9s--- 任务B --9s-- 任务C (注意:9s是我们的设置的任务执行间隔时间)。
但是执行了10s的话,下一个任务相当于延迟了1s,那就currentTime - task.period设置延迟的时间执行。否则正常执行(executionTime + task.period)。
三、Timer:任务的调度器
创建Timer对象,就启动了TimerThread线程。任务规划器:
这里的执行的线程是具体的你代码中哪个线程调用的schedule方法。在我写的代码里由于我是在main方法中直接写的话,这里的是主线程中执行的。
下面是我看完源码之后的理解:
1、一个Timer可以看做一个线程在调度任务。这样有一定的缺点是下一个任务必须等待下一个任务的执行。可以看做任务的串行执行。也就是可以看做同步。如果要是任务执行的时间与设置的时间间隔不冲突的话,这个不是问题。
2、TimerThread线程循环的在干活,不会退出。必须我们手动调用timer.cancel()方法才会退出。这就涉及到了TimerThread与其它线程通信的问题了,比如主线程,也是它的父线程。一般此时的可能退出了,这样的话,没有线程跟TimerThread通信,那它就会成功一个无用的线程。类似于Linux中的“僵尸进程”,线程资源没办法回收。就算它的父线程不退出的话,也办法释放线程资源,因为TimerThread完全封装到了Timer里面,它干完了活没办法通知父线程,父线程自然不会调用timer.cancel()。
Timer#cancel代码如下:
相关文章推荐
- java中使用线程实现Timer(定时器)原理和源码
- java中使用线程实现Timer(定时器)原理和源码
- java中使用线程实现Timer(定时器)原理和源码
- java中使用线程实现Timer(定时器)原理和源码
- java中使用线程实现Timer(定时器)原理和源码
- java中使用线程实现Timer(定时器)原理和源码
- java中使用线程实现Timer(定时器)原理和源码
- java中使用线程实现Timer(定时器)原理和源码
- java中使用线程实现Timer(定时器)原理和源码
- java中使用线程实现Timer(定时器)原理和源码
- java中使用线程实现Timer(定时器)原理和源码
- java中使用线程实现Timer(定时器)原理和源码
- java中使用线程实现Timer(定时器)原理和源码
- java中使用线程实现Timer(定时器)原理和源码
- java中使用线程实现Timer(定时器)原理和源码
- java中使用线程实现Timer(定时器)原理和源码
- java中使用线程实现Timer(定时器)原理和源码
- [转载] Java集合---HashMap源码剖析
- Java集合---HashMap源码剖析
- Java Timer 定时器的使用