带你学会区分Scheduled Thread Pool Executor 与Timer
摘要:本文简单介绍下Scheduled Thread Pool Executor类与Timer类的区别,Scheduled Thread Pool Executor类相比于Timer类来说,究竟有哪些优势,以及二者分别实现任务调度的简单示例。
本文分享自华为云社区《【高并发】ScheduledThreadPoolExecutor与Timer的区别和简单示例》,作者:冰 河 。
JDK 1.5开始提供Scheduled Thread Pool Executor类,Scheduled Thread Pool Executor类继承Thread Pool Executor类重用线程池实现了任务的周期性调度功能。在JDK 1.5之前,实现任务的周期性调度主要使用的是Timer类和Timer Task类。本文,就简单介绍下Scheduled Thread Pool Executor类与Timer类的区别,Scheduled Thread Pool Executor类相比于Timer类来说,究竟有哪些优势,以及二者分别实现任务调度的简单示例。
二者的区别
线程角度
- Timer是单线程模式,如果某个TimerTask任务的执行时间比较久,会影响到其他任务的调度执行。
- Scheduled Thread Pool Executor是多线程模式,并且重用线程池,某个Scheduled Future Task任务执行的时间比较久,不会影响到其他任务的调度执行。
系统时间敏感度
- Timer调度是基于操作系统的绝对时间的,对操作系统的时间敏感,一旦操作系统的时间改变,则Timer的调度不再精确。
- Scheduled Thread Pool Executor调度是基于相对时间的,不受操作系统时间改变的影响。
是否捕获异常
- Timer不会捕获Timer Task抛出的异常,加上Timer又是单线程的。一旦某个调度任务出现异常,则整个线程就会终止,其他需要调度的任务也不再执行。
- Scheduled Thread Pool Executor基于线程池来实现调度功能,某个任务抛出异常后,其他任务仍能正常执行。
任务是否具备优先级
- Timer中执行的Timer Task任务整体上没有优先级的概念,只是按照系统的绝对时间来执行任务。
- Scheduled Thread Pool Executor中执行的Scheduled Future Task类实现了java.lang.Comparable 接口和java.util.concurrent.Delayed 接口,这也就说明了Scheduled Future Task类中实现了两个非常重要的方法,一个是java.lang.Comparable 接口的compare To方法,一个是java.util.concurrent.Delayed接口的get Delay方法。在Scheduled Future Task类中compare To方法实现了任务的比较,距离下次执行的时间间隔短的任务会排在前面,也就是说,距离下次执行的时间间隔短的任务的优先级比较高。而get Delay 方法则能够返回距离下次任务执行的时间间隔。
是否支持对任务排序
- Timer不支持对任务的排序。
- Scheduled Thread Pool Executor类中定义了一个静态内部类Delayed Work Queue ,Delayed Work Queue 类本质上是一个有序队列,为需要调度的每个任务按照距离下次执行时间间隔的大小来排序
能否获取返回的结果
- Timer中执行的Timer Task类只是实现了java.lang.Runnable 接口,无法从Timer Task 中获取返回的结果。
- Scheduled Thread Pool Executor中执行的Scheduled Future Task类继承了Future Task 类,能够通过Future来获取返回的结果。
通过以上对Scheduled Thread Pool Executor 类和Timer类的分析对比,相信在JDK 1.5之后,就没有使用Timer来实现定时任务调度的必要了。
二者简单的示例
这里,给出使用Timer和Scheduled Thread Pool Executor 实现定时调度的简单示例,为了简便,我这里就直接使用匿名内部类的形式来提交任务。
Timer类简单示例
源代码示例如下所示。
package io.binghe.concurrent.lab09;
import java.util.Timer;
import java.util.TimerTask;
/**
* @author binghe
* @version 1.0.0
* @description 测试Timer
*/
public class TimerTest {
public static void main(String[] args) throws InterruptedException {
Timer timer = new Timer();
timer.scheduleAtFixedRate(new TimerTask() {
@Override
public void run() {
System.out.println("测试Timer类");
}
}, 1000, 1000);
Thread.sleep(10000);
timer.cancel();
}
}
运行结果如下所示。
测试Timer类
测试Timer类
测试Timer类
测试Timer类
测试Timer类
测试Timer类
测试Timer类
测试Timer类
测试Timer类
测试Timer类
Scheduled Thread Pool Executor类简单示例
源代码示例如下所示。
package io.binghe.concurrent.lab09;
import java.util.concurrent.*;
/**
* @author binghe
* @version 1.0.0
* @description 测试ScheduledThreadPoolExecutor
*/
public class ScheduledThreadPoolExecutorTest {
public static void main(String[] args) throws InterruptedException {
ScheduledExecutorService scheduledExecutorService = Executors.newScheduledThreadPool(3);
scheduledExecutorService.scheduleAtFixedRate(new Runnable() {
@Override
public void run() {
System.out.println("测试测试ScheduledThreadPoolExecutor");
}
}, 1, 1, TimeUnit.SECONDS);
//主线程休眠10秒
Thread.sleep(10000);
System.out.println("正在关闭线程池...");
// 关闭线程池
scheduledExecutorService.shutdown();
boolean isClosed;
// 等待线程池终止
do {
isClosed = scheduledExecutorService.awaitTermination(1, TimeUnit.DAYS);
System.out.println("正在等待线程池中的任务执行完成");
} while(!isClosed);
System.out.println("所有线程执行结束,线程池关闭");
}
}
运行结果如下所示。
测试测试ScheduledThreadPoolExecutor
测试测试ScheduledThreadPoolExecutor
测试测试ScheduledThreadPoolExecutor
测试测试ScheduledThreadPoolExecutor
测试测试ScheduledThreadPoolExecutor
测试测试ScheduledThreadPoolExecutor
测试测试ScheduledThreadPoolExecutor
测试测试ScheduledThreadPoolExecutor
测试测试ScheduledThreadPoolExecutor
正在关闭线程池...
测试测试ScheduledThreadPoolExecutor
正在等待线程池中的任务执行完成
所有线程执行结束,线程池关闭
注意:关于Timer和Scheduled Thread Pool Executor 还有其他的使用方法,这里,我就简单列出以上两个使用示例,更多的使用方法大家可以自行实现。
带你学会区分Scheduled Thread Pool Executor 与Timer的更多相关文章
- 实例分析Scheduled Thread Pool Executor与Timer的区别
摘要:JDK 1.5开始提供Scheduled Thread PoolExecutor类,Scheduled Thread Pool Executor类继承Thread Pool Executor类重 ...
- 通过Thread Pool Executor类解析线程池执行任务的核心流程
摘要:ThreadPoolExecutor是Java线程池中最核心的类之一,它能够保证线程池按照正常的业务逻辑执行任务,并通过原子方式更新线程池每个阶段的状态. 本文分享自华为云社区<[高并发] ...
- 8000字详解Thread Pool Executor
摘要:Java是如何实现和管理线程池的? 本文分享自华为云社区<JUC线程池: ThreadPoolExecutor详解>,作者:龙哥手记 . 带着大厂的面试问题去理解 提示 请带着这些问 ...
- ThreadPoolExecutor – Java Thread Pool Example(如何使用Executor框架创建一个线程池)
Java thread pool manages the pool of worker threads, it contains a queue that keeps tasks waiting to ...
- ThreadPoolExecutor – Java Thread Pool Example
https://www.journaldev.com/1069/threadpoolexecutor-java-thread-pool-example-executorservice Java t ...
- ThreadPoolExecutor – Java Thread Pool Example(java线程池创建和使用)
Java thread pool manages the pool of worker threads, it contains a queue that keeps tasks waiting to ...
- DUBBO Thread pool is EXHAUSTED!
一.问题 在测试环境遇到的异常信息,如下: 16-10-17 00:00:00.033 [New I/O server worker #1-6] WARN com.alibaba.dubbo.com ...
- [Done][DUBBO] dubbo Thread pool is EXHAUSTED!
异常信息: com.alibaba.dubbo.remoting.ExecutionException: class com.alibaba.dubbo.remoting.transport.disp ...
- The threads in the thread pool will process the requests on the connections concurrently.
https://docs.oracle.com/javase/tutorial/essential/concurrency/pools.html Most of the executor implem ...
- Anti Pattern - ThreadLocal variables with Thread Pool(转)
In a previous post, I wrote the usage and benefits of ThreadLocal based instance variables in concur ...
随机推荐
- z函数|exkmp|拓展kmp 笔记+图解
题外话,我找个什么时间把kmp也加一下图解 z函数|exkmp 别担心 这个exkmp和kmp没毛点关系,请放心食用. 本文下标以1开始,为什么?因为1开始就不需要进行长度和下标的转换,长度即下标. ...
- 3种web会话管理的方式(session)
阅读目录 https://www.cnblogs.com/lyzg/p/6067766.html 1. 基于server端session的管理 2. cookie-based的管理方式 3. tok ...
- Net 高级调试之六:对象检查之值类型、应用类型、数组和异常的转储
一.简介 今天是<Net 高级调试>的第六篇文章.记得我刚接触 Net 框架的时候,还是挺有信心的,对所谓的值类型和引用类型也能说出自己的见解,毕竟,自己一直在努力.当然这些见解都是书本上 ...
- STM8 STM32 GPIO 细节配置问题
在MCU的GPIO配置中我们经常需要预置某一 IO 上电后为某一固定电平, 如果恰好我们需要上电后的某IO为高电平, 那么在配置GPIO的流程上面需要特别注意. 配置如下: (以下问题仅在STM8 / ...
- Log4j入门使用
前言 本篇文章主要在于,初步了解log4j,以及对它的简单使用 欢迎点赞 收藏 留言评论 私信必回哟 博主将持续更新学习记录收获,友友们有任何问题可以在评论区留言 @ 目录 一,log4j简介 二,配 ...
- 🔥🔥Java开发者的Python快速进修指南:迭代器(Iterator)与生成器
这一篇内容可能相对较少,但是迭代器在Java中是有用处的.因此,我想介绍一下Python中迭代器的使用方法.除了写法简单之外,Python的迭代器还有一个最大的不同之处,就是无法直接判断是否还有下一个 ...
- 公司敏感数据被上传Github,吓得我赶紧改提交记录
大家好,我是小富- 说个事吧!最近公司发生了一个事故,有同事不小心把敏感数据上传到了GitHub上,结果被安全部门扫描出来了.这件事导致公司对所有员工进行了一次数据安全的培训.对于这个事我相信,有点工 ...
- 关于C#接口的用法详细解答,附上案例说明!
接口 C#中的接口是一种定义了一组方法.属性和事件的类型.它只包含成员的声明,而不包含任何实现.接口可以被类通过实现的方式使用,从而使类能够具有接口定义的行为. 接口在C#中被定义为使用interfa ...
- Chrome扩展开发实战:快速填充表单
大家好,我是 dom 哥.我正在写关于 Chrome 扩展开发的系列文章,感兴趣的可以 点个小星星 . 填表单是打工人经常面对的场景,作为一个前端,我经常开发一些PC端的页面,它们主要由表单和表格构成 ...
- docker开启或关闭<开机自启容器>
启动容器时设置 docker run --restart=always 启动完成也可以修改 docker update --restart=always <容器ID> 想取消容器自启 do ...