写点什么

带你学会区分 Scheduled Thread Pool Executor 与 Timer

发布于: 1 小时前

​​摘要:本文简单介绍下 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 还有其他的使用方法,这里,我就简单列出以上两个使用示例,更多的使用方法大家可以自行实现。


点击关注,第一时间了解华为云新鲜技术~

发布于: 1 小时前阅读数: 3
用户头像

提供全面深入的云计算技术干货 2020.07.14 加入

华为云开发者社区,提供全面深入的云计算前景分析、丰富的技术干货、程序样例,分享华为云前沿资讯动态,方便开发者快速成长与发展,欢迎提问、互动,多方位了解云计算! 传送门:https://bbs.huaweicloud.com/

评论

发布
暂无评论
带你学会区分Scheduled Thread Pool Executor 与Timer