实例分析Scheduled Thread Pool Executor与Timer的区别
摘要:JDK 1.5开始提供Scheduled Thread PoolExecutor类,Scheduled Thread Pool Executor类继承Thread Pool Executor类重用线程池实现了任务的周期性调度功能。
本文分享自华为云社区《【高并发】ScheduledThreadPoolExecutor与Timer的区别和简单示例》,作者:冰 河 。
JDK 1.5开始提供ScheduledThreadPoolExecutor类,ScheduledThreadPoolExecutor类继承ThreadPoolExecutor类重用线程池实现了任务的周期性调度功能。在JDK 1.5之前,实现任务的周期性调度主要使用的是Timer类和TimerTask类。本文,就简单介绍下ScheduledThreadPoolExecutor类与Timer类的区别,ScheduledThreadPoolExecutor类相比于Timer类来说,究竟有哪些优势,以及二者分别实现任务调度的简单示例。
二者的区别
线程角度
- Timer是单线程模式,如果某个TimerTask任务的执行时间比较久,会影响到其他任务的调度执行。
- ScheduledThreadPoolExecutor是多线程模式,并且重用线程池,某个ScheduledFutureTask任务执行的时间比较久,不会影响到其他任务的调度执行。
系统时间敏感度
- Timer调度是基于操作系统的绝对时间的,对操作系统的时间敏感,一旦操作系统的时间改变,则Timer的调度不再精确。
- ScheduledThreadPoolExecutor调度是基于相对时间的,不受操作系统时间改变的影响。
是否捕获异常
- Timer不会捕获TimerTask抛出的异常,加上Timer又是单线程的。一旦某个调度任务出现异常,则整个线程就会终止,其他需要调度的任务也不再执行。
- ScheduledThreadPoolExecutor基于线程池来实现调度功能,某个任务抛出异常后,其他任务仍能正常执行。
任务是否具备优先级
- Timer中执行的TimerTask任务整体上没有优先级的概念,只是按照系统的绝对时间来执行任务。
- ScheduledThreadPoolExecutor中执行的ScheduledFutureTask类实现了java.lang.Comparable接口和java.util.concurrent.Delayed接口,这也就说明了ScheduledFutureTask类中实现了两个非常重要的方法,一个是java.lang.Comparable接口的compareTo方法,一个是java.util.concurrent.Delayed接口的getDelay方法。在ScheduledFutureTask类中compareTo方法方法实现了任务的比较,距离下次执行的时间间隔短的任务会排在前面,也就是说,距离下次执行的时间间隔短的任务的优先级比较高。而getDelay方法则能够返回距离下次任务执行的时间间隔。
是否支持对任务排序
- Timer不支持对任务的排序。
- ScheduledThreadPoolExecutor类中定义了一个静态内部类DelayedWorkQueue,DelayedWorkQueue类本质上是一个有序队列,为需要调度的每个任务按照距离下次执行时间间隔的大小来排序
能否获取返回的结果
- Timer中执行的TimerTask类只是实现了java.lang.Runnable接口,无法从TimerTask中获取返回的结果。
- ScheduledThreadPoolExecutor中执行的ScheduledFutureTask类继承了FutureTask类,能够通过Future来获取返回的结果。
通过以上对ScheduledThreadPoolExecutor类和Timer类的分析对比,相信在JDK 1.5之后,就没有使用Timer来实现定时任务调度的必要了。
二者简单的示例
这里,给出使用Timer和ScheduledThreadPoolExecutor实现定时调度的简单示例,为了简便,我这里就直接使用匿名内部类的形式来提交任务。
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类
ScheduledThreadPoolExecutor类简单示例
源代码示例如下所示。
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和ScheduledThreadPoolExecutor还有其他的使用方法,这里,我就简单列出以上两个使用示例,更多的使用方法大家可以自行实现。
实例分析Scheduled Thread Pool Executor与Timer的区别的更多相关文章
- 通过Thread Pool Executor类解析线程池执行任务的核心流程
摘要:ThreadPoolExecutor是Java线程池中最核心的类之一,它能够保证线程池按照正常的业务逻辑执行任务,并通过原子方式更新线程池每个阶段的状态. 本文分享自华为云社区<[高并发] ...
- [图解tensorflow源码] 线程池模块分析 (CPU thread pool device)
- 从一个简单的小实例分析JSP+Servelt与JSP+Struts2框架的区别
最近在学struts2,struts2相比以前的JSP+Servlet,在处理流程上的更简单,我们就一个小实例来具体分析一下. 实例内容如下: 实现一个简单的注册页面包括:用户名.密码.重复密码.年龄 ...
- 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 ...
- [源码分析] 并行分布式任务队列 Celery 之 Timer & Heartbeat
[源码分析] 并行分布式任务队列 Celery 之 Timer & Heartbeat 目录 [源码分析] 并行分布式任务队列 Celery 之 Timer & Heartbeat 0 ...
- DUBBO Thread pool is EXHAUSTED!
一.问题 在测试环境遇到的异常信息,如下: 16-10-17 00:00:00.033 [New I/O server worker #1-6] WARN com.alibaba.dubbo.com ...
- MySQL学习分享--Thread pool实现
基于<MySQL学习分享--Thread pool>对Thread pool架构设计的详细了解,本文主要对Thread pool的实现进行分析,并根据Mariadb和Percona提供的开 ...
随机推荐
- NOIP提高组模拟赛26
A. LCIS 蓝书原题,CF10D 弱化版 首先直接把 LIS 和 LCS 合起来设计一个 DP . 设 \(dp_{i,j}\) 表示 \(A_{1\dots i}\) 和 \(B_{1\dots ...
- Win10环境下使用Flask配合Celery异步推送实时/定时消息(Socket.io)/2020年最新攻略
原文转载自「刘悦的技术博客」https://v3u.cn/a_id_163 首先得明确一点,和Django一样,在2020年Flask 1.1.1以后的版本都不需要所谓的三方库支持,即Flask-Ce ...
- Three---面向对象与面向过程/属性和变量/关于self/一些魔法方法的使用/继承/super方法/多态
python的面向对象 面向对象与面向过程 面向过程 面向过程思想:需要实现一个功能的时候,看重的是开发的步骤和过程,每一个步骤都需要自己亲力亲为,需要自己编写代码(自己来做) 面向对象 面向对象的三 ...
- Taurus.MVC WebAPI 入门开发教程8:WebAPI文档与自动化测试。
系列目录 1.Taurus.MVC WebAPI 入门开发教程1:框架下载环境配置与运行. 2.Taurus.MVC WebAPI 入门开发教程2:添加控制器输出Hello World. 3.Tau ...
- Canvas 笔记目录
Canvas 基础笔记 初次认识 Canvas Canvas 线性图形(一):路径 Canvas 线性图形(二):圆形 Canvas 线性图形(三):曲线 Canvas 线性图形(四):矩形 Canv ...
- Excel 逻辑函数(二):AND 和 OR
前言 AND 函数是且:OR 函数是或.AND 函数中的条件必须都满足才返回 TRUE:OR 函数中的条件只要满足一个就返回 TRUE.AND 和 OR 的参数最多允许有 30 个. AND [题目] ...
- HTML <option> 标签的属性:selected ; disabled ; label ; value;
HTML <option> 标签的属性:selected ; disabled ; label ; value; 1. selected="selected" sel ...
- 未完待续【java】JavaEE学习路线总览
这个博客会详细介绍各种技术的知识点,从零基础到入门,充当引路的作用. 同时也会发布一些Swift语言.c#语言.Xcode开发的学习笔记.一些阅读的笔记(部分读书笔记无法发布). 目前1-43的Jav ...
- VM虚拟机安装
VM虚拟机安装 1.安装vm虚拟机软件 1.1 双击打开虚拟机文件 1.2 根据向导安装 下一步 安装好了 不要着急点完成在 安装目录中有许可证. 1.3激活操作 2.虚拟机原理简介 3. 新建虚拟机 ...
- JAVA反序列化漏洞修复解决方法
MyObject类建立了Serializable模块,而且重新写过了readObject()变量,仅有建立了Serializable模块的类的目标才能够被实例化,沒有建立此模块的类将无法使他们的任意状 ...