Timer执行不结束
public class MyTask extends TimerTask {
public void run() {
System.out.println("运行了代码");
}
}
//延迟5000毫秒后执行
Timer timer=new Timer();
timer.schedule(new MyTask(),5000);
我们发现他执行了一次MyTask后,线程未关闭,查询源码发现,他内部有一个Thread,run方法设置为while(true)因此,他不会关闭。如果需要和Thread一样执行完成就关闭,可以在task的run方法里面执行timer.cancel。
当mainLoop抛出任何异常时,线程将结束并将任务队列清空退出
public void run() {
try {
mainLoop();
} finally {
// Someone killed this Thread, behave as if Timer cancelled
synchronized(queue) {
newTasksMayBeScheduled = false;
queue.clear(); // Eliminate obsolete references
}
}
}
private void mainLoop() {
while (true) {
......
}
}
Timer执行延迟
由于TimerTask是以队列的方法一个一个被顺序执行,所以执行的时间有可能和预期的时间不一致,因为前面的任务有可能消耗的时间比较长,则后面的时间会被延迟
Timer的api
//延迟delay毫秒后,执行一次
schedule(TimerTask task, long delay)
//延迟到time时间开始,执行一次
schedule(TimerTask task, Date time)
//延迟delay毫秒后,每period执行一次
//按照顺序执行,不会有非线程安全问题
//前一个任务执行时间长,则后面的任务也会延迟执行,按照前一个任务执行结束的时间+period
schedule(TimerTask task, long delay, long period)
//从time时间开始,每period执行一次
//time时间早于当前时间,立即执行
//按照顺序执行,不会有非线程安全问题
//前一个任务执行时间长,则后面的任务也会延迟执行,按照前一个任务执行结束的时间+period
schedule(TimerTask task, Date time, long period)
//延迟delay毫秒后,每period执行一次
//按照顺序执行,不会有非线程安全问题
//固定频率,不会因为前一个任务执行时间长而是后一个任务延迟执行
scheduleAtFixedRate(TimerTask task, long delay, long period)
//从time时间开始,每period执行一次
//按照顺序执行,不会有非线程安全问题
//time时间早于当前时间,立即执行
//固定频率,不会因为前一个任务执行时间长而是后一个任务延迟执行
scheduleAtFixedRate(TimerTask task, Date firstTime, long period)
//将任务队列的全部任务清空,任务销毁
//有时他不能立即停止,看源码,他执行cancel的时候需要拿到queue锁,当他无法拿到的时候,就需要等待
//public void cancel() {
// synchronized(queue) {
// thread.newTasksMayBeScheduled = false;
// queue.clear();
// queue.notify(); // In case queue was already empty.
// }
// }
cancel();