ScheduledThreadPoolExecutor使用指南
ScheduledThreadPoolExecutor是Timer的多线程实现版本,JDK官方推荐使用。
ScheduledThreadPoolExecutor用于替代Timer。是接口ScheduledExecutorService的子类,主要方法说明如下:
/**
* 调度一个task,经过delay(时间单位由参数unit决定)后开始进行调度,仅仅调度一次
*/
public ScheduledFuture<?> schedule(Runnable command, long delay, TimeUnit unit); /**
* 同上,支持参数不一样
*/
public <V> ScheduledFuture<V> schedule(Callable<V> callable,long delay, TimeUnit unit); /**
* 周期性调度任务,在delay后开始调度,适合执行时间比“间隔”短的任务
* 并且任务开始时间的间隔为period,即“固定间隔”执行。
* 如果任务执行的时间比period长的话,会导致该任务延迟执行,不会同时执行!
* 如果任务执行过程抛出异常,后续不会再执行该任务!
*/
public ScheduledFuture<?> scheduleAtFixedRate(Runnable command, long initialDelay ,long period ,TimeUnit unit); /**
* Timer所没有的“特色”方法,称为“固定延迟(delay)”调度,适合执行时间比“间隔”长的任务
* 在initialDelay后开始调度该任务
* 随后,在每一次执行终止和下一次执行开始之间都存在给定的延迟period
* 即下一次任务开始的时间为:上一次任务结束时间(而不是开始时间) + delay时间
* 如果任务执行过程抛出异常,后续不会再执行该任务!
*/
public ScheduledFuture<?> scheduleWithFixedDelay(Runnable command,long initialDelay ,long delay ,TimeUnit unit);
示例代码:
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit; public class ScheduledExecutorTest {
//线程池能按时间计划来执行任务,允许用户设定计划执行任务的时间,int类型的参数是设定
//线程池中线程的最小数目。当任务较多时,线程池可能会自动创建更多的工作线程来执行任务
//此处用Executors.newSingleThreadScheduledExecutor()更佳。
public ScheduledExecutorService scheduExec = Executors.newScheduledThreadPool(1);
//启动计时器
public void lanuchTimer(){
Runnable task = new Runnable() {
public void run() {
throw new RuntimeException();
}
};
scheduExec.scheduleWithFixedDelay(task, 1000*5, 1000*10, TimeUnit.MILLISECONDS);
}
//添加新任务
public void addOneTask(){
Runnable task = new Runnable() {
public void run() {
System.out.println("welcome to china");
}
};
scheduExec.scheduleWithFixedDelay(task, 1000*1, 1000, TimeUnit.MILLISECONDS);
} public static void main(String[] args) throws Exception {
ScheduledExecutorTest test = new ScheduledExecutorTest();
test.lanuchTimer();
Thread.sleep(1000*5);//5秒钟之后添加新任务
test.addOneTask();
}
}
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才执行。
示例代码:
import java.util.Timer;
import java.util.TimerTask; public class TimerTest {
private Timer timer = new Timer();
//启动计时器
public void lanuchTimer(){
timer.schedule(new TimerTask(){
public void run() {
throw new RuntimeException();
}
}, 1000*3, 500);
}
//向计时器添加一个任务
public void addOneTask(){
timer.schedule(new TimerTask(){
public void run(){
System.out.println("hello world");
}
}, 1000*1,1000*5);
} public static void main(String[] args) throws Exception {
TimerTest test = new TimerTest();
test.lanuchTimer();
Thread.sleep(1000*5);//5秒钟之后添加一个新任务
test.addOneTask();
}
}
ScheduledThreadPoolExecutor使用指南的更多相关文章
- Java 并发工具包 java.util.concurrent 用户指南
1. java.util.concurrent - Java 并发工具包 Java 5 添加了一个新的包到 Java 平台,java.util.concurrent 包.这个包包含有一系列能够让 Ja ...
- Java并发编程-并发工具包(java.util.concurrent)使用指南(全)
1. java.util.concurrent - Java 并发工具包 Java 5 添加了一个新的包到 Java 平台,java.util.concurrent 包.这个包包含有一系列能够让 Ja ...
- Java_并发工具包 java.util.concurrent 用户指南(转)
译序 本指南根据 Jakob Jenkov 最新博客翻译,请随时关注博客更新:http://tutorials.jenkov.com/java-util-concurrent/index.html.本 ...
- (转)并发编程 – Concurrent 用户指南
原文出处: 高广超 译序 本指南根据 Jakob Jenkov 最新博客翻译,请随时关注博客更新:http://tutorials.jenkov.com/java-util-concurrent/in ...
- 并发编程 – Concurrent 用户指南--转
1. java.util.concurrent – Java 并发工具包 Java 5 添加了一个新的包到 Java 平台,java.util.concurrent 包.这个包包含有一系列能够让 Ja ...
- Java多线程编程实战指南(核心篇)读书笔记(五)
(尊重劳动成果,转载请注明出处:http://blog.csdn.net/qq_25827845/article/details/76730459冷血之心的博客) 博主准备恶补一番Java高并发编程相 ...
- Java并发指南11:解读 Java 阻塞队列 BlockingQueue
解读 Java 并发队列 BlockingQueue 转自:https://javadoop.com/post/java-concurrent-queue 最近得空,想写篇文章好好说说 java 线程 ...
- JavaScript权威指南 - 函数
函数本身就是一段JavaScript代码,定义一次但可能被调用任意次.如果函数挂载在一个对象上,作为对象的一个属性,通常这种函数被称作对象的方法.用于初始化一个新创建的对象的函数被称作构造函数. 相对 ...
- UE4新手之编程指南
虚幻引擎4为程序员提供了两套工具集,可共同使用来加速开发的工作流程. 新的游戏类.Slate和Canvas用户接口元素以及编辑器功能可以使用C++语言来编写,并且在使用Visual Studio 或 ...
随机推荐
- (转)Unity与3ds Max的单位关系(使用FBX文件)
版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明.本文链接:https://blog.csdn.net/a1780531/article/deta ...
- 个人项目wc(Java)
个人项目(Java) 一丶Github地址:https://github.com/SAH2019/S ...
- 8个有意思的JavaScript面试题
摘要: 神奇的JS系列. 作者:前端小智 原文:8个问题看你是否真的懂 JS Fundebug经授权转载,版权归原作者所有. JavaScript 是一种有趣的语言,我们都喜欢它,因为它的性质.浏览器 ...
- 【原创】Airflow调用talend
核心原理 因为talend job build出来是一个可直接运行的程序,可以通过shell命名启动job进程,因此可以使用airflow的bashoperator调用生成好的talend job包里 ...
- Python从零开始——字符串String
一:Python字符串有哪些内容 二:Python字符串操作符 三:Python字符串格式化——占位符格式化 四:Python字符串格式化——format()函数 五:Python字符串常用操作函数
- kolla部署openstack allinone,报错APIError: 500 Server Error: Internal Server Error (\"oci runtime error: container_linux.go:235: starting container process caused \"container init exited prematurely
使用 kolla-ansible 部署 opnenstack:stein 执行 kolla-ansible -i ./all-in-one deploy 开始自动化部署 在部署过程中报错,报错信息如下 ...
- Git 克隆远程仓库到本地
Git 克隆远程仓库到本地 参考 $ git clone --help https://git-scm.com/book/zh/v2/Git-%E5%9F%BA%E7%A1%80-%E8%8E%B7% ...
- NOIP 2005 采药
洛谷 P1048 采药 洛谷传送门 JDOJ 1277: [NOIP2005]采药 T3 JDOJ传送门 Description 辰辰是个天资聪颖的孩子,他的梦想是成为世界上最伟大的医师.为此,他 ...
- 使用 SQLContext 可以从现有的 RDD 或数据源创建 DataFrames 报错?
报错情况: 解决方法: SQLContext可能需要自己创建. 所以,先运行var sqlContext=new org.apache.spark.sql SQLContext(sc).即可. 之后再 ...
- eclipse中查找类、方法及变量被引用的地方
1.选中要查看的类.方法或变量,然后Ctrl+Shift+G或右键-->References--->Project,就可以找到它所有被引用的地方. 2.对于方法,还可以通过右键--> ...