[转帖]实例分析 Scheduled Thread Pool Executor 与 Timer 的区别

实例,分析,scheduled,thread,pool,executor,timer,区别 · 浏览次数 : 0

小编点评

**Timer 与 ScheduledThreadPoolExecutor 的区别** | 特性 | Timer | ScheduledThreadPoolExecutor | |---|---|---| | 线程模型 | 单线程 | 多线程 | | 调度方式 | 操作系统绝对时间 | 相对时间 | | 捕获异常 | 不会捕获 | 可以捕获异常 | | 任务排序 | 不支持 | 支持 | | 方法 | java.util.Timer、TimerTask | java.util.concurrent.ScheduledFutureTask | **ScheduledThreadPoolExecutor 的优势** * 使用线程池实现任务执行,提高效率。 * 避免操作系统时间敏感度问题。 * 在任务执行过程中捕获异常。 * 支持对任务的排序。 **使用示例** **Timer** ```java import java.util.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(); } } ``` **ScheduledThreadPoolExecutor** ```java import java.util.concurrent.*; 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); // 关闭线程池 scheduledExecutorService.shutdown(); } } ```

正文

https://my.oschina.net/u/4526289/blog/5584251

 

 
摘要: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 的区别相似的内容:

[转帖]实例分析 Scheduled Thread Pool Executor 与 Timer 的区别

https://my.oschina.net/u/4526289/blog/5584251 摘要:JDK 1.5 开始提供 Scheduled Thread PoolExecutor 类,Scheduled Thread Pool Executor 类继承 Thread Pool Executor

[转帖]Linux系统指令 top 之 %si 占用高,分析实例

https://www.coonote.com/linux-note/linux-top-si-high-instance.html 续“top %wa 高的问题”之后,又遇到top之%si过高(高峰时段超过95%)的问题。 %wa高,说明磁盘忙。譬如磁盘读写次数非常高。 %si高,是否说明软中断忙

[转帖]crash工具分析Kdump下vmcore文件常用命令总结(三)(实例易懂)

一、简介 本文主要介绍使用crash工具对kdump生成的vmcore文件进行分析,解析常见的crash命令,前面已讲述两章关于Kdump的内容,读者感兴趣可以点击下面的链接: 1、Kdump调试机理总结(一) 2、Kdump配置及使用详细总结(二) 系统产生异常时,触发Kdump机制,启动捕获内核

[转帖]一个用于辅助分析‘Java内存泄露’的小工具

https://www.jianshu.com/p/658cb6cbfe61 histo对比工具 这是一个用于辅助分析‘Java内存泄露’的小工具 源码地址 实现原理 分析fgc前后的类实例对象分布变化来辅助判断 如果多次fgc后,一个类的对象实例没有发生变化或者越来越多,则需要重点排查 操作步骤

[转帖]优雅的分析redis中的内存数据之RCT

https://www.zhihu.com/column/c_1087047428959608832?utm_id=0 目前我们EC Bigdata team 运维公司 4个 Redis 集群,300+ Redis 实例,500G+ 的内存数据,我们想要分析业务是否有误用,以提高资源利用率。伴随着业

[转帖]JVM(3)之垃圾回收(GC垃圾收集器+垃圾回收算法+安全点+记忆集与卡表+并发可达性分析......)

《深入理解java虚拟机》+宋红康老师+阳哥大厂面试题2总结整理 一、堆的结构组成 堆位于运行时数据区中是线程共享的。一个进程对应一个jvm实例。一个jvm实例对应一个运行时数据区。一个运行时数据区有一个堆空间。 java堆区在jvm启动的时候就被创建了,其空间大小也就被确定了(堆是jvm管理的最大

[转帖]Linux下strace调试系统应用参数总结(附实例操作讲解)

文章目录 一、简介二、常用参数详解三、实例详解3.1 跟踪具体进程3.2 监控具体程序执行过程 四、其他相关知识链接 一、简介 strace命令是一个集诊断、调试、统计与一体的Linux 用户空间跟踪器,我们可以使用strace对应用的系统调用、信号传递和进程状态变更的监控结果来对应用进行分析,以达

[转帖]Linux下strace调试系统应用参数总结(附实例操作讲解)

文章目录 一、简介二、常用参数详解三、实例详解3.1 跟踪具体进程3.2 监控具体程序执行过程 四、其他相关知识链接 一、简介 strace命令是一个集诊断、调试、统计与一体的Linux 用户空间跟踪器,我们可以使用strace对应用的系统调用、信号传递和进程状态变更的监控结果来对应用进行分析,以达

[转帖]性能之内存篇

http://www.manongjc.com/detail/62-xzlnozethfhhibi.html 本文章向大家介绍性能之内存篇,主要内容包括其使用实例、应用技巧、基本知识点总结和需要注意事项,具有一定的参考价值,需要的朋友可以参考一下。 最近笔者在看性能分析相关的是知识,就特意针对内存整

[转帖]Core dump实战分析之Java版

https://www.jianshu.com/p/2cdf71f99209 Core dump实战分析(Java版) 背景 项目中的battleserver进程在某一段时间总是crash,无法找到具体Crash原因 Java通过JNI调用Luajit 那么进程Crash如何找到JNI的堆栈(C层)