Java线程和多线程(十)——TimerTask
来源:互联网 发布:苹果mac怎么更新不了 编辑:程序博客网 时间:2024/06/14 14:57
Java中的java.util.Timer
是一个工具类,可以用于调度一个线程在将来的某一个时刻执行特定的任务。Java Timer类可以将一个任务定时执行一次,或者是以后以每隔一定的时间间隔来触发一次。
Java TimerTask
java.util.TimerTask
是一个抽象类,也同时实现了Runnable
接口的。我们可以继承这个类来创建我们自己的TimerTask
之后由Timer
来调度。
Java Timer举例
Java Timer类是线程安全的,多个线程可以共享一个Timer对象而不需要额外的同步操作。Timer类会使用java.util.TaskQueue
来将Task以一定的时间间隔加入到队列之中,而且,在任何时候仅仅能有一个线程在运行TimerTask。举例来说,开发者创建了一个Timer每隔10秒来执行一次,但是单线程的执行需要使用20秒,那么Timer对象会持续将任务添加到队列中,只要线程的执行完成了,它会通知队列中另一个线程来立刻执行。
Java Timer类通过对象的wait
和notify
方法来调度任务。
参见如下代码:
package com.sapphire.threads;import java.util.Date;import java.util.Timer;import java.util.TimerTask;public class MyTimerTask extends TimerTask { @Override public void run() { System.out.println("Timer task started at:"+new Date()); completeTask(); System.out.println("Timer task finished at:"+new Date()); } private void completeTask() { try { //assuming it takes 20 secs to complete the task Thread.sleep(20000); } catch (InterruptedException e) { e.printStackTrace(); } } public static void main(String args[]){ TimerTask timerTask = new MyTimerTask(); //running timer task as daemon thread Timer timer = new Timer(true); timer.scheduleAtFixedRate(timerTask, 0, 10*1000); System.out.println("TimerTask started"); //cancel after sometime try { Thread.sleep(120000); } catch (InterruptedException e) { e.printStackTrace(); } timer.cancel(); System.out.println("TimerTask cancelled"); try { Thread.sleep(30000); } catch (InterruptedException e) { e.printStackTrace(); } }}
需要注意的是,上面的一个线程的执行会花掉20秒,但是Java的Timer对象调度的执行间隔是10秒执行一次,所以输出如下:
TimerTask startedTimer task started at:Fri Oct 14 12:59:27 CST 2016Timer task finished at:Fri Oct 14 12:59:47 CST 2016Timer task started at:Fri Oct 14 12:59:47 CST 2016Timer task finished at:Fri Oct 14 13:00:07 CST 2016Timer task started at:Fri Oct 14 13:00:07 CST 2016Timer task finished at:Fri Oct 14 13:00:27 CST 2016Timer task started at:Fri Oct 14 13:00:27 CST 2016Timer task finished at:Fri Oct 14 13:00:47 CST 2016Timer task started at:Fri Oct 14 13:00:47 CST 2016Timer task finished at:Fri Oct 14 13:01:07 CST 2016Timer task started at:Fri Oct 14 13:01:07 CST 2016TimerTask cancelledTimer task finished at:Fri Oct 14 13:01:27 CST 2016
输出也确认了一点,就是如果一个任务已经开始执行了,那么Timer会等待它的完成,而一旦完成,Timer会立刻开始执行队列中的下一个任务。
Java的对象可以以守护线程的方式来调度相关的任务。Timer的cancel()
方法是用来结束Timer并抛弃其他的调度任务的。然而,这个方法不会影响现在正在执行的任务,而是让其继续运行下去。如果我们将Timer的运行配置为守护线程,那么无论我们是否调用cancel()
方法,一旦用户线程完成执行,Timer都会立刻结束掉。
Timer类中包含多个schedule()
方法,可以调度任务在指定时间执行一次,或者在一些延迟后来执行。Timer类中也包含了一些scheduleAtFixedRate()
方法来以指定的时间间隔来运行一些任务。
注意:当使用Timer来进行任务调度的时候,开发者需要确认无时间间隔一定要大于线程的执行时间。否则,任务的队列会变得越来越长而实际的任务也会总是在执行。
前面的描述也相当于隐含着提到了Timer的可能的错误行为,那就是Timer执行任务的方式。Timer的实现是内部包含一个队列,和一个线程,然后来定时将任务添加到执行队列之中的。
public class Timer { private final TaskQueue queue = new TaskQueue(); private final TimerThread thread = new TimerThread(queue);}
这样就可能出现问题,如果将2个
TimerTask
加入到Timer中进行执行,如果其中一个Timer执行的比较忙,而另一个需要执行的又比较快,可能就会出现问题。举例来说,两个任务,一个每隔300秒执行一次,一个每隔5秒执行一次,如果第一个任务执行了20秒才结束,那么因为上面实现的原因,会将第二个任务阻塞20秒,而一口气执行四次。所以开发者在使用Timer
来进行任务调度的时候,需要考虑性能以及可能出现的错误行为。
- Java线程和多线程(十)——TimerTask
- Java多线程2-线程协作、Timer和TimerTask
- Java多线程2-线程协作、Timer和TimerTask
- Java线程(3)Timer和TimerTask
- Java线程(五)----Timer和TimerTask
- 【Java多线程】之十:Timer and TimerTask
- Java多线程总结(3)— Timer 和 TimerTask深入分析
- Java 线程——Timer & TimerTask
- Java线程——特殊线程TimerTask定时器
- Java 中 Timer 和 TimerTask实现多线程
- Java多线程(五):Timer和TimerTask
- Java线程和多线程(六)——守护线程
- Java线程(五):Timer和TimerTask
- Java线程(四):Timer和TimerTask
- Java线程(四):Timer和TimerTask
- Java线程(四):Timer和TimerTask
- Java线程(五):Timer和TimerTask
- Java线程(五):Timer和TimerTask
- codeVS 3115 高精度练习之减法
- 数据结构实验之栈一:进制转换(java实现)
- PHP中foreach的用法和实例
- 旧版本ubuntu更新软件的方法
- android使用HttpURLConnection获取网站源码
- Java线程和多线程(十)——TimerTask
- Web前端开发的问题汇总
- Java基础知识学习之面向对象一
- Linux基础——构建工具链
- SHELL编程基础
- Couldn't find a tree builder with the features you requested: lxml 问题解决
- 机器学习分类篇-支持向量机SVM上
- 理解jvm的ClassLoader分析-基础篇
- HDU5923——Prediction(数据结构,并查集)