(java并发)ScheduledThreadPoolExcutor
来源:互联网 发布:北京和隆优化 编辑:程序博客网 时间:2024/06/06 01:45
Timer 的优点在于简单易用,但由于所有任务都是由同一个线程来调度,因此所有任务都是串行执行的,同一时间只能有一个任务在执行,前一个任务的延迟或异常都将会影响到之后的任务。
我们关于定时/周期操作都是通过Timer来实现的。但是Timer有以下几种危险
a. Timer是基于绝对时间的。容易受系统时钟的影响。
b. Timer只新建了一个线程来执行所有的TimeTask。所有TimeTask可能会相关影响
c. Timer不会捕获TimerTask的异常,只是简单地停止。这样势必会影响其他TimeTask的执行。
2.ScheduledThreadPoolExecutor
鉴于 Timer 的上述缺陷,Java 5 推出了基于线程池设计的ScheduledThreadPoolExecutor。其设计思想是,每一个被调度的任务都会由线程池中一个线程去执行,因此任务是并发执行的,相互之间不会受到干扰。需 要注意的是,只有当任务的执行时间到来时,ScheduedExecutor 才会真正启动一个线程,其余时间 ScheduledExecutor 都是在轮询任务的状态。
有以下四个调度器的方法:
public ScheduledFuture<?> schedule(Runnable command, long delay, TimeUnit unit);public <V> ScheduledFuture<V> schedule(Callable<V> callable, long delay, TimeUnit unit);public ScheduledFuture<?> scheduleAtFixedRate(Runnable command, long initialDelay, long period, TimeUnit unit);public ScheduledFuture<?> scheduleWithFixedDelay(Runnable command, long initialDelay, long delay, TimeUnit unit);
那么这四个方法有什么区别呢?其实第一个和第二个区别不大,一个是Runnable、一个是Callable,内部包装后是一样的效果;所以把头两个方法几乎当成一种调度,那么三种情况分别是:
1、 进行一次延迟调度:延迟delay这么长时间,单位为:TimeUnit传入的的一个基本单位,例如:TimeUnit.SECONDS属于提供好的枚举信息;(适合于方法1和方法2)。
2、 多次调度,每次依照上一次预计调度时间进行调度,例如:延迟2s开始,5s一次,那么就是2、7、12、17,如果中间由于某种原因导致线程不够用,没有得到调度机会,那么接下来计算的时间会优先计算进去,因为他的排序会被排在前面,有点类似Timer中的:scheduleAtFixedRate方法,只是这里是多线程的,它的方法名也叫:scheduleAtFixedRate,所以这个是比较好记忆的(适合方法3)
3、 多次调度,每次按照上一次实际执行的时间进行计算下一次时间,同上,如果在第7秒没有被得到调度,而是第9s才得到调度,那么计算下一次调度时间就不是12秒,而是9+5=14s,如果再次延迟,就会延迟一个周期以上,也就会出现少调用的情况(适合于方法3);
4、 最后补充execute方法是一次调度,期望被立即调度,时间为空
public class ScheduledThreadPoolExecutorDemo { public static void main(String[] args) {ScheduledThreadPoolExecutor scheduledExecutor = new ScheduledThreadPoolExecutor(1);/** * new timeTaskForException() 要执行的任务线程 * 1000:延迟多长时间执行 * 2000: 每隔多少长时间执行一次 * TimeUnit.MILLISECONDS:时间单位 */scheduledExecutor.scheduleAtFixedRate(new timeTaskForException(), 1000, 2000, TimeUnit.MILLISECONDS);scheduledExecutor.scheduleAtFixedRate(new timeTaskForPrintSYSTime(), 1000, 3000, TimeUnit.MILLISECONDS);}static class timeTaskForException implements Runnable{public void run() {throw new RuntimeException();}}static class timeTaskForPrintSYSTime implements Runnable {public void run() {System.out.println(System.nanoTime());}}}
- (java并发)ScheduledThreadPoolExcutor
- (java多线程并发)控制并发线程数的Semaphore、ScheduledThreadPoolExcutor、BlockingQueue、ReadWriteLock
- java并发--并发集合
- Java 并发:并发背景
- Java 并发:并发背景
- java 并发
- Java并发
- Java并发
- Java并发
- java 并发
- Java 并发
- Java 并发
- Java并发
- java 并发
- Java 并发
- java并发
- Java 并发
- java并发
- WDK 7600《HELLO WORLD》
- ByteArrayOutputStream 理解
- Can not find a java.io.InputStream with the name [inputStream] in the invocation stack. Check the <p
- MyBatis:Parameter Maps collection does not contain value for 的问题解决
- Volecity模板引擎学习笔记<一>
- (java并发)ScheduledThreadPoolExcutor
- CString转int _ttoi() _tcstoul() Format ASSERT() Format的用法
- Leetcode First Missing Positive
- MySQL数据库查询操作
- 数据库事务
- Struts2学习笔记——Struts2与Spring整合
- NOIP 2013 积木大赛 贪心
- 简单的Gson转换json数据
- Redis开源代码读书笔记六(sds模块)