【高并发】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还有其他的使用方法,这里,我就简单列出以上两个使用示例,更多的使用方法大家可以自行实现。
【高并发】ScheduledThreadPoolExecutor与Timer的区别和简单示例的更多相关文章
- 实例分析Scheduled Thread Pool Executor与Timer的区别
摘要:JDK 1.5开始提供Scheduled Thread PoolExecutor类,Scheduled Thread Pool Executor类继承Thread Pool Executor类重 ...
- nginx应用总结(2)--突破高并发的性能优化
在日常的运维工作中,经常会用到nginx服务,也时常会碰到nginx因高并发导致的性能瓶颈问题.今天这里简单梳理下nginx性能优化的配置(仅仅依据本人的实战经验而述,如有不妥,敬请指出~) 一.这里 ...
- 优秀开源项目之三:高性能、高并发、高扩展性和可读性的网络服务器架构State Threads
译文在后面. State Threads for Internet Applications Introduction State Threads is an application library ...
- 聊聊高并发(十八)理解AtomicXXX.lazySet方法
看过java.util.concurrent.atomic包里面各个AtomicXXX类实现的同学应该见过lazySet方法.比方AtomicBoolean类的lazySet方法 public fin ...
- 聊聊高并发(二十八)解析java.util.concurrent各个组件(十) 理解ReentrantReadWriteLock可重入读-写锁
这篇讲讲ReentrantReadWriteLock可重入读写锁,它不仅是读写锁的实现,而且支持可重入性. 聊聊高并发(十五)实现一个简单的读-写锁(共享-排他锁) 这篇讲了怎样模拟一个读写锁. 可重 ...
- Nginx突破高并发的性能优化 - 运维笔记
在日常的运维工作中,经常会用到nginx服务,也时常会碰到nginx因高并发导致的性能瓶颈问题.今天这里简单梳理下nginx性能优化的配置(仅仅依据本人的实战经验而述,如有不妥,敬请指出~) 一.这里 ...
- 2.redis 和 memcached 有什么区别?redis 的线程模型是什么?为什么 redis 单线程却能支撑高并发?
作者:中华石杉 面试题 redis 和 memcached 有什么区别?redis 的线程模型是什么?为什么 redis 单线程却能支撑高并发? 面试官心理分析 这个是问 redis 的时候,最基本的 ...
- redis和memcached有什么区别?redis的线程模型是什么?为什么单线程的redis比多线程的memcached效率要高得多(为什么redis是单线程的但是还可以支撑高并发)?
1.redis和memcached有什么区别? 这个事儿吧,你可以比较出N多个区别来,但是我还是采取redis作者给出的几个比较吧 1)Redis支持服务器端的数据操作:Redis相比Memcache ...
- 2020-05-25:MQ应用场景、Kafka和rabbit区别?kafka为什么支撑高并发? 来自
福哥答案2020-05-25: 应用场景:解耦.异步.削峰.区别如下:特性 ActiveMQ RabbitMQ RocketMQ Kafka单机吞吐量 万级,比 RocketMQ.Kafka 低一个数 ...
随机推荐
- Möbius 反演注记
目录 基本理论基础 数论函数 线性筛 Mobius 反演 Dirichlet 卷积 数论分块 / 整除分块 拆函数 时间复杂度分析 基本形式 GCD 形 万能 Prod 的莫比乌斯反演 正常例题 YY ...
- Java---注解与反射
前言 近期在学习SSM框架的过程中发现在SSM框架中大量用到了反射与注解的知识,要想学好SSM框架,必须将注解与反射熟记于心,尤其是对Java反射机制的理解. 对于我这种记性不好的人来说"基 ...
- 小试牛刀:Go 反射帮我把 Excel 转成 Struct
背景 起因于最近的一项工作:我们会定义一些关键指标来衡量当前系统的健康状态,然后配置对应的报警规则来进行监控报警.但是当前的报警规则会产生大量的误报,需要进行优化.我所负责的是将一些和用户行为指标相关 ...
- 技术分享 | MySQL数据误删除的总结
欢迎来到 GreatSQL社区分享的MySQL技术文章,如有疑问或想学习的内容,可以在下方评论区留言,看到后会进行解答 内容提要 用delete语句 使用drop.truncate删除表以及drop删 ...
- Chapter 09 - NSUndoManager (C#实现 + 全网原创)
此例子针对NSDocument实现了tableview 每一行添加/删除的undo/redo,以及每一个单元格内容编辑的undo/redo.基于NSDocument类的实现.PersonModel + ...
- CF1450E 资本主义Capitalism(差分约束)
题面 点此看题 没有永远的朋友,只有永远的利益 在这个黑漆漆的社会上,有 n n n 个布衣百姓,他们在利益驱使下成为金钱的奴隶,看不到属于生活的阳光.在茫茫奔途中,他们相互扶持,结交了有 m m m ...
- C# 开发过程中常见错误记录及解决说明
1.异常了类型: 1.1.1.1 异常错误信息:An error occurred while updating the entries. See the inner exception for de ...
- CodeForces - 1629C
Problem - 1629C - Codeforces 题意: 一个序列,每次可以从开头选择一个长度为K的序列,然后得到这个序列的MEX(最小的未出现的数),问最后可以求得的字典大小最大的序列是多少 ...
- Html飞机大战(七):发射第一颗子弹
好家伙,终于到子弹了 我们先来理一理思路: 子弹由飞机射出,所以我们把发射子弹的方法写在英雄类中 当然了,子弹也必须有自己独立的类 后期会有很多子弹射出,所以一个个将子弹类实例化肯定是不对的 我们也需 ...
- 第九十八篇:Web的储存机制LocalStorage
好家伙 1.什么是LocalStorage? LocalStorage 是一种 web 端的存储机制, 它使得由 JavaScript 编写的网站或者应用可以无限期的在浏览器中存储并访问数据. Loc ...