admin管理员组文章数量:1794759
多线程学习(2):ScheduledThreadPoolExecutor 与 schedule 之小结
2018年7月9日08:48:58
欢迎扫二维码关注公众号,获取技术干货【1】前言
线程池与任务定时执行,一是项目随处可见的一种技术,二是自己还需打打扎实基础;不可以仅仅局限于业务的实现,要去体会底层的思想;
【2】关于线程池ThreadPoor与Timer的使用
2.1 Java提供的Time类可以周期性地或者延期执行任务,但是有时我们需要并行执行同样的任务,这个时候如果创建多个Time对象会给系统带来负担,解决办法是将定时任务放到线程池中执行。
Java的scheduledThreadPoolExecutor类实现了ScheduledExecutorService接口中定义的以不同方法执行任务的方法。
2.2 ScheduleThreadPoolExecutor与Timer相比的优势
(1)Timer是基于绝对时间的延时执行或周期执行,当系统时间改变,则任务的执行会受到的影响。而ScheduleThreadPoolExecutore中,任务时基于相对时间进行周期或延时操作。
(2)Timer也可以提交多个TimeTask任务,但只有一个线程来执行所有的TimeTask,这样并发性受到影响。而ScheduleThreadPoolExecutore可以设定池中线程的数量。
(3)Timer不会捕获TimerTask的异常,只是简单地停止,这样势必会影响其他TimeTask的执行。而ScheduleThreadPoolExecutore中,如果一个线程因某些原因停止,线程池可以自动创建新的线程来维护池中线程的数量。
2.3 自jdk1.5开始,Java开始提供ScheduledThreadPoolExecutor类来支持周期性任务的调度,在这之前,这些工作需要依靠Timer/TimerTask或者其它第三方工具来完成。但Timer有着不少缺陷,如Timer是单线程模式,调度多个周期性任务时,如果某个任务耗时较久就会影响其它任务的调度;如果某个任务出现异常而没有被catch则可能导致唯一的线程死掉而所有任务都不会再被调度。ScheduledThreadPoolExecutor解决了很多Timer存在的缺陷。JDK1.5之前的Timer和TimerTask类已经过时了。
通过如上的介绍,可以对比一下Timer和ScheduledThreadPoolExecutor:
单线程 | 多线程 |
单个任务执行时间影响其他任务调度 | 多线程,不会影响 |
基于绝对时间 | 基于相对时间 |
一旦执行任务出现异常不会捕获,其他任务得不到执行 | 多线程,单个任务的执行不会影响其他线程 |
所以,在JDK1.5之后,应该没什么理由继续使用Timer进行任务调度了。
【3】ScheduledThreadPoolExecutor 工作原理
【4】源码
【5】实现例子
BusinessPool.java:
package test2; import java.util.concurrent.ScheduledThreadPoolExecutor; import java.util.concurrent.ThreadFactory; import java.util.concurrent.TimeUnit; import java.util.concurrent.atomic.AtomicInteger; public class BusinessPool { private ScheduledThreadPoolExecutor executor; BusinessPool() { } public static class BusinessPoolThreadFactory implements ThreadFactory { final ThreadGroup group = Thread.currentThread().getThreadGroup(); final AtomicInteger threadNumber = new AtomicInteger(1); final String namePrefix = "business-pool"; @Override public Thread newThread(Runnable r) { Thread t = new Thread(group, r, namePrefix + threadNumber.getAndIncrement(), 0); if (t.isDaemon()) t.setDaemon(false); if (t.getPriority() != Thread.NORM_PRIORITY) t.setPriority(Thread.NORM_PRIORITY); return t; } } public void init() { this.executor = new ScheduledThreadPoolExecutor(1, new BusinessPoolThreadFactory()); } public void schedule(Runnable runnable, long delay, TimeUnit unit) { executor.schedule(runnable, delay, unit); } public void execute(Runnable runnable) { executor.execute(runnable); } }
test.java:
package test2; import java.util.concurrent.TimeUnit; public class test23 { public static void main(String[] args) { BusinessPool businessPool = new BusinessPool(); businessPool.init(); businessPool.schedule(new Runnable() { @Override public void run() { System.out.println("Hello world 0_0|||"); } }, 3, TimeUnit.SECONDS); } }输出结果(延时3s执行线程):
Hello world 0_0|||
参考博文:www.jianshu/p/925dba9f5969
画外音:
保持积极,保持锻炼,保持刻苦。
本文标签: 小结多线程ScheduledThreadPoolExecutorschedule
版权声明:本文标题:多线程学习(2):ScheduledThreadPoolExecutor 与 schedule 之小结 内容由林淑君副主任自发贡献,该文观点仅代表作者本人, 转载请联系作者并注明出处:http://www.xiehuijuan.com/baike/1686477379a71886.html, 本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容,一经查实,本站将立刻删除。
发表评论