Timer
2016-04-28 21:24
316 查看
Timer和TimerTask详解
1.Timer和TimerTask
Timer是jdk中提供的一个定时器工具,使用的时候会在主线程之外起一个单独的线程执行指定的计划任务,可以
指定执行一次或反复执行多次。 TimerTask是一个实现了Runnable接口的抽象类,代表一个可以被Timer执行的任
务。
2.终止Timer线程
默认情况下,创建的timer线程会一直执行,主要有下面四种方式终止Timer线程:
(1)调用Timer的cancel方法
(2)把Timer线程设置为daemon线程,(new Timer(true)创建daemon线程),在JVM里,如果所有用户线程结束,
那么守护线程也会被终止,不过这种方法一般不用。
(3)当所有任务执行结束后,删除对应timer对象的引用,线程也会被终止。
(4)调用System.exit方法终止程序。
3.关于cancel方式终止线程
这种方式终止timer线程,jdk的实现比较巧妙
cancel方法的源码:
public void cancel(){
synchronized(queue){
thread.newTasksMayBeScheduled=false;
queue.clear();
queue.notify();
}
}
没有显示的线程stop方法,而是调用了queue的clear方法和queue的notify方法,clear是个自定义方法,notify
是object自带的方法,很明显是去唤醒wait方法的。
clear方法:
void clear(){
for(int i==1;i<=size;i++){
queue[i]=null;
}
size=0;
}
clear()方法很简单,就是去清空queue,queue是一个TimerTask的数组,然后把queue的size重置为0,变成empty。
new Timer()代码:
public Timer(){
this("Timer-"+serialNumber());
}
public Timer(String name){
thread.setName(name);
thread.start();
}
内部变量thread
TimerThread thread=new TimerThread(queue);
不是原生的Thread,是自定义的类TimerThread。这个类实现了Thread类,重写了run方法,如下:
public void run(){
try{
mainLoop();
}finally{
synchronized(queue){
newTaskMayBeScheduled=false;
queue.clear();
}
}
}
最后是这个mainLoop方法
private void mainLoop(){
while(true){
try{
TimerTask task;
boolean taskFired;
synchronized(queue){
while(queue.isEmpty&&newTaskMayBeScheduled){
queue.wait();
}
if(queue.isEmpty()){
break;
}
}
}
}
}
可看到,之前的notify就是通知到这个wait,然后clear方法在notify之前作了清空数组的操作,所以会break,
线程执行结束,退出。
5.反复执行一个任务
通过调用三个参数的schedule方法实现,最后一个参数是执行间隔,单位毫秒
6.schedule VS scheduleAtFixedRate
这两个方法都是任务调度方法,他们之间区别是,schedule会保证任务的间隔是按照定义period参数严格执行的,
如果某一次调度时间比较长,那么后面的时间会顺延,保证间隔都是period,而scheduleAtFixedRate是严格按
照调度时间来的,如果某次调度时间太长了,那么会通过缩短间隔的方式保证下一次调度在预定时间内执行。
注意点:
每一个Timer仅对应唯一一个线程
Timer不保证任务执行的非常准确
Timer类的线程是安全的。
1.Timer和TimerTask
Timer是jdk中提供的一个定时器工具,使用的时候会在主线程之外起一个单独的线程执行指定的计划任务,可以
指定执行一次或反复执行多次。 TimerTask是一个实现了Runnable接口的抽象类,代表一个可以被Timer执行的任
务。
2.终止Timer线程
默认情况下,创建的timer线程会一直执行,主要有下面四种方式终止Timer线程:
(1)调用Timer的cancel方法
(2)把Timer线程设置为daemon线程,(new Timer(true)创建daemon线程),在JVM里,如果所有用户线程结束,
那么守护线程也会被终止,不过这种方法一般不用。
(3)当所有任务执行结束后,删除对应timer对象的引用,线程也会被终止。
(4)调用System.exit方法终止程序。
3.关于cancel方式终止线程
这种方式终止timer线程,jdk的实现比较巧妙
cancel方法的源码:
public void cancel(){
synchronized(queue){
thread.newTasksMayBeScheduled=false;
queue.clear();
queue.notify();
}
}
没有显示的线程stop方法,而是调用了queue的clear方法和queue的notify方法,clear是个自定义方法,notify
是object自带的方法,很明显是去唤醒wait方法的。
clear方法:
void clear(){
for(int i==1;i<=size;i++){
queue[i]=null;
}
size=0;
}
clear()方法很简单,就是去清空queue,queue是一个TimerTask的数组,然后把queue的size重置为0,变成empty。
new Timer()代码:
public Timer(){
this("Timer-"+serialNumber());
}
public Timer(String name){
thread.setName(name);
thread.start();
}
内部变量thread
TimerThread thread=new TimerThread(queue);
不是原生的Thread,是自定义的类TimerThread。这个类实现了Thread类,重写了run方法,如下:
public void run(){
try{
mainLoop();
}finally{
synchronized(queue){
newTaskMayBeScheduled=false;
queue.clear();
}
}
}
最后是这个mainLoop方法
private void mainLoop(){
while(true){
try{
TimerTask task;
boolean taskFired;
synchronized(queue){
while(queue.isEmpty&&newTaskMayBeScheduled){
queue.wait();
}
if(queue.isEmpty()){
break;
}
}
}
}
}
可看到,之前的notify就是通知到这个wait,然后clear方法在notify之前作了清空数组的操作,所以会break,
线程执行结束,退出。
5.反复执行一个任务
通过调用三个参数的schedule方法实现,最后一个参数是执行间隔,单位毫秒
6.schedule VS scheduleAtFixedRate
这两个方法都是任务调度方法,他们之间区别是,schedule会保证任务的间隔是按照定义period参数严格执行的,
如果某一次调度时间比较长,那么后面的时间会顺延,保证间隔都是period,而scheduleAtFixedRate是严格按
照调度时间来的,如果某次调度时间太长了,那么会通过缩短间隔的方式保证下一次调度在预定时间内执行。
注意点:
每一个Timer仅对应唯一一个线程
Timer不保证任务执行的非常准确
Timer类的线程是安全的。
相关文章推荐
- 《常见算法和数据结构》优先队列(1)——API和初等实现
- 已知若干个城市的地图,求从一个城市到另外一个城市的路径,要求路径中经过的城市最少。
- 《Algorithms算法》笔记:优先队列(1)——API和初等实现
- iptables 基本讲解
- 删除一个无头单链表的非尾节点
- Qt之校验器
- XDU-1035 数独 (模拟)
- iOS开发总结之 view的frame、center和和view的bounds之间的区别
- NOIP201402比例化简
- 第九周 技术博客发表 网页设计打地鼠游戏
- 【笔试/面试】—— Linux 查看 cpu 和内存使用情况
- hdu 5671 Matrix(BC——思维题)
- ldpack工作日记-2016/4/28
- Android5.0/6.0新特性
- 用MFC 写高斯(gauss)列主元消去法和doolittle三角分解法
- JavaSE入门学习33:Java集合框架概述
- Java多线程编程-生产者,消费者
- hbase表结构以及操作
- 转: android 实现效果特效
- 解读vmstat中的ACTIVE/INACTIVE MEMORY