Timer与ScheduledExecutorService间的抉择
java.util.Timer计时器有管理任务延迟执行("如1000ms后执行任务")以及周期性执行("如每500ms执行一次该任务")。
但是,Timer存在一些缺陷,因此你应该考虑使用ScheduledThreadPoolExecutor作为代替品,Timer对调度的支持是基于绝对时间,而不是相对时间的,
由此任务对系统时钟的改变是敏感的;ScheduledThreadExecutor只支持相对时间。
Timer的另一个问题在于,如果TimerTask抛出未检查的异常,Timer将会产生无法预料的行为。
Timer线程并不捕获异常,所以TimerTask抛出的未检查的异常会终止timer线程。
这种情况下,Timer也不会再重新恢复线程的执行了;它错误的认为整个Timer都被取消了。
此时,已经被安排但尚未执行的TimerTask永远不会再执行了,新的任务也不能被调度了。
个人总结:timer的bug:60秒执行一次的话,如果用户修改了时间的话 那么时针都会归0,本来是临近10秒执行的时候timer又会重新计时一次 再等60才执行。
测试Timer的例子

1 package com.bill99.test;
2
3 import java.util.Timer;
4 import java.util.TimerTask;
5
6 public class TimerTest {
7 private Timer timer = new Timer();
8 //启动计时器
9 public void lanuchTimer(){
10 timer.schedule(new TimerTask(){
11 public void run() {
12 throw new RuntimeException();
13 }
14 }, 1000*3, 500);
15 }
16 //向计时器添加一个任务
17 public void addOneTask(){
18 timer.schedule(new TimerTask(){
19 public void run(){
20 System.out.println("hello world");
21 }
22 }, 1000*1,1000*5);
23 }
24
25 public static void main(String[] args) throws Exception {
26 TimerTest test = new TimerTest();
27 test.lanuchTimer();
28 Thread.sleep(1000*5);//5秒钟之后添加一个新任务
29 test.addOneTask();
30 }
31 }

运行该程序,Timer会抛出一个RumtimeException和java.lang.IllegalStateException:Timer already cancelled.
常言道,真是祸不单行,Timer还将它的问题传染给下一个倒霉的调用者,这个调用者原本试图提交一个TimerTask的,你可能希望程序会一直运行下去,然而实际情况如程序所示5秒钟后就中止了,还伴随着一个异常,异常的消息是"Timer already cancelled"。ScheduledThreadPoolExector妥善地处理了这个异常的任务,所以说在java5.0或更高的JDK中,几乎没有理由再使用Timer了。
用ScheduledThreadPoolExector改进后的例子

1 package com.bill99.test;
2
3 import java.util.concurrent.Executors;
4 import java.util.concurrent.ScheduledExecutorService;
5 import java.util.concurrent.TimeUnit;
6
7 public class ScheduledExecutorTest {
8 //线程池能按时间计划来执行任务,允许用户设定计划执行任务的时间,int类型的参数是设定
9 //线程池中线程的最小数目。当任务较多时,线程池可能会自动创建更多的工作线程来执行任务
10 //此处用Executors.newSingleThreadScheduledExecutor()更佳。
11 public ScheduledExecutorService scheduExec = Executors.newScheduledThreadPool(1);
12 //启动计时器
13 public void lanuchTimer(){
14 Runnable task = new Runnable() {
15 public void run() {
16 throw new RuntimeException();
17 }
18 };
19 scheduExec.scheduleWithFixedDelay(task, 1000*5, 1000*10, TimeUnit.MILLISECONDS);
20 }
21 //添加新任务
22 public void addOneTask(){
23 Runnable task = new Runnable() {
24 public void run() {
25 System.out.println("welcome to china");
26 }
27 };
28 scheduExec.scheduleWithFixedDelay(task, 1000*1, 1000, TimeUnit.MILLISECONDS);
29 }
30
31 public static void main(String[] args) throws Exception {
32 ScheduledExecutorTest test = new ScheduledExecutorTest();
33 test.lanuchTimer();
34 Thread.sleep(1000*5);//5秒钟之后添加新任务
35 test.addOneTask();
36 }
37 }

Timer与ScheduledExecutorService间的抉择的更多相关文章
- Java 多线程之Timer与ScheduledExecutorService
1.Timer管理延时任务的缺陷 a.以前在项目中也经常使用定时器,比如每隔一段时间清理项目中的一些垃圾文件,每个一段时间进行数据清洗:然而Timer是存在一些缺陷的,因为Timer在执行定时任务时只 ...
- 任务调度的方式:Timer、ScheduledExecutorService、spring task、quartz、XXL-JOB、Elastic-Job
任务调度 定时任务调度:基于给定的时间点.给定的时间间隔.给定的执行次数自动执行的任务. Timer 介绍 Timer,简单无门槛,一般也没人用. Timer位于java.util包下,其内部包含且仅 ...
- java定时任务Timer与ScheduledExecutorService<转>
在我们编程过程中如果需要执行一些简单的定时任务,无须做复杂的控制,我们可以考虑使用JDK中的Timer定时任务来实现.下面LZ就其原理.实例以及Timer缺陷三个方面来解析java Timer定时器. ...
- Timer和ScheduledExecutorService区别
Timer特点: 1.一个Timer只占用一个线程 timer有多个timerTask的情况,如果一个timerTask有执行时间过长,其它的timerTask就会被耽误 2.如果TimerTas ...
- java 几种常见的定时器
今天闲着没事就总结了一下在java中常用的几种定时器. 主要有3种java.util.Timer, ScheduledExecutorService和quartz 一.Timer 举个简单例子.每隔5 ...
- Android -- 从源码解析Handle+Looper+MessageQueue机制
1,今天和大家一起从底层看看Handle的工作机制是什么样的,那么在引入之前我们先来了解Handle是用来干什么的 handler通俗一点讲就是用来在各个线程之间发送数据的处理对象.在任何线程中,只要 ...
- [从源码学设计]蚂蚁金服SOFARegistry之时间轮的使用
[从源码学设计]蚂蚁金服SOFARegistry之时间轮的使用 目录 [从源码学设计]蚂蚁金服SOFARegistry之时间轮的使用 0x00 摘要 0x01 业务领域 1.1 应用场景 0x02 定 ...
- SpringBoot定时任务 - 经典定时任务设计:时间轮(Timing Wheel)案例和原理
Timer和ScheduledExecutorService是JDK内置的定时任务方案,而业内还有一个经典的定时任务的设计叫时间轮(Timing Wheel), Netty内部基于时间轮实现了一个Ha ...
- [Java线程] Java线程池ExecutorService
示例 import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; import java.u ...
随机推荐
- TCP面试题之为什么会有TIME_WAIT状态
1.确保有足够的时间让对方收到ACK包:(一来一去刚好是2MSL) 2.避免新旧连接混淆 MSL(最大报文段的生成时间)在RFC793中规定hi2分钟,实际应用是30秒,1分钟,2分钟等:
- Idea下maven的配置和使用
maven的主要功能就是依赖管理,jar包仓库.和C#中的NuGet仓库差不多.另外也提供打包构建,启动插件等功能.下面主要讲一下,在使用Idea开发时,maven的配置和使用. maven的安装和配 ...
- 移动端px转rem的两种方法
rem使用方法: rem ,root element,即相对于根元素的大小,浏览器默认字符大小为16px,此时1rem相当于16px. 方法1 设置font-size: body{font-size ...
- *LOJ#2306. 「NOI2017」蔬菜
$n \leq 100000$种蔬菜,每个蔬菜有:一单位价格:卖第一单位时额外价格:总量:每天腐烂量.每天能卖$m \leq 10$单位蔬菜,多次询问:前$k \leq 100000$天最多收入多少. ...
- datalist、repearter、gridview显示行号的三种方法 或者是获取datalist行id
原文发布时间为:2009-05-06 -- 来源于本人的百度文章 [由搬家工具导入] 1. if you are using SQL Server, try select identity(int,1 ...
- mac 重置mysql root密码
1. 关闭mysql服务 sudo /usr/local/mysql/support-files/mysql.server stop 如果出现Starting mysqld daemon with d ...
- IIS 配置缓存
IIS8设置应用程序池-高级设置-启动模式:AlwaysRunning 应用程序池-高级设置-进程模型-闲置超时:1740 (分钟) 应用程序-高级设置-常规-预加载已启用:True
- Dialog和软键盘在屏幕上的并存问题:
最近做添加门店,门店昵称自动根据文字变化去搜索后台数据,但是一搜索软键盘就关闭了,感觉用户体验不太好.一开始根本不知道啥问题,找了半天才发现是网络请求dialog加载导致软件盘隐藏的,后面直接把dia ...
- (9)JavaScript-DOM(文档对象模型)
DOM是针对 HTML 和 XML 文档的一个 API ,描绘了一个层次化的节点树,允许开发人员添加.移除和修改页面的某一部分 一.节点层次 <html> <head> &l ...
- 第13届景驰-埃森哲杯广东工业大学ACM程序设计大赛【待补】
[链接]:https://www.nowcoder.com/acm/contest/90#question