JDK源码(二十六):Timer
Posted jdkSpring
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了JDK源码(二十六):Timer相关的知识,希望对你有一定的参考价值。
Timer是jdk中提供的一个定时器工具,使用的时候会在主线程之外起一个单独的线程执行指定的计划任务,可以指定执行一次或者反复执行多次。而Timer的使用需要TimeTask类的配合,TimerTask为抽象类,需要重写类中的run方法。
从上面的源码上可以看出,TimerTask类是一个抽象类,其中定义了任务的各种状态及任务的锁对象,此类只有3个方法,而我们需重写其中的run方法表示我们要执行的代码。
Timer
类名
public class Timer
变量
schedule(TimerTask task, long delay, long period)
sched(TimerTask task, long time, long period)
下面主要来看下周期性调度通过什么方式实现的,在Timer类中TimerThread这个类实现计时器的任务执行线程,该线程等待计时器队列上的任务,在任务触发时执行它们,重新安排重复任务,并从队列中删除已取消的任务和已花费的非重复任务。TimerThread继承Thread类,在Timer类的构造方法中开启线程执行start()方法,通过mainLoop()方法实现任务调度。
实例
Timer timer = new Timer();
TimerTask timerTask = new TimerTask() {
public void run() {
HttpRequest.getZizhi();
index++;
if (index > 1){
timer.cancel();
}
}
};
timer.schedule(timerTask, 0, 2000);
schedule方法 和 scheduleAtFixedRate方法
schedule:每次执行完当前任务后,然后间隔一个period的时间再执行下一个任务,因此执行时间会不断延后。比如每次的任务执行时间为2秒,period时间为1秒,那么就相当于每3秒执行一次任务。
scheduleAtFixedRate:每次执行时间为上一次任务开始起向后推一个period间隔,也就是说下次执行时间相对于上一次任务开始的时间点,因此执行时间不会延后,但是存在任务并发执行的问题。
并发问题:比如任务每间隔3秒执行一次,突然有一次任务执行了6秒钟,因为6秒钟可以执行两次任务,所以下次执行就会一下子执行两次该任务。
缺点
首先Timer对调度的支持是基于绝对时间的,而不是相对时间,所以它对系统时间的改变非常敏感。
其次Timer线程是不会捕获异常的,如果TimerTask抛出的了未检查异常则会导致Timer线程终止,同时Timer也不会重新恢复线程的执行,他会错误的认为整个Timer线程都会取消。同时,已经被安排但尚未执行的TimerTask也不会再执行了,新的任务也不能被调度。
因为Timer底层是使用一个单线来实现多个Timer任务处理的,所有任务都是由同一个线程来调度,所有任务都是串行执行,意味着同一时间只能有一个任务得到执行,而前一个任务的延迟或者异常会影响到之后的任务。
这些缺点可以通过ScheduledExecutorService来代替
源码(1.8)
以上是关于JDK源码(二十六):Timer的主要内容,如果未能解决你的问题,请参考以下文章
Vue.js 源码分析(二十六) 高级应用 作用域插槽 详解
企业分布式微服务云SpringCloud SpringBoot mybatis (二十六)集成apidoc