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使用指南的更多相关文章

  1. Java 并发工具包 java.util.concurrent 用户指南

    1. java.util.concurrent - Java 并发工具包 Java 5 添加了一个新的包到 Java 平台,java.util.concurrent 包.这个包包含有一系列能够让 Ja ...

  2. Java并发编程-并发工具包(java.util.concurrent)使用指南(全)

    1. java.util.concurrent - Java 并发工具包 Java 5 添加了一个新的包到 Java 平台,java.util.concurrent 包.这个包包含有一系列能够让 Ja ...

  3. Java_并发工具包 java.util.concurrent 用户指南(转)

    译序 本指南根据 Jakob Jenkov 最新博客翻译,请随时关注博客更新:http://tutorials.jenkov.com/java-util-concurrent/index.html.本 ...

  4. (转)并发编程 – Concurrent 用户指南

    原文出处: 高广超 译序 本指南根据 Jakob Jenkov 最新博客翻译,请随时关注博客更新:http://tutorials.jenkov.com/java-util-concurrent/in ...

  5. 并发编程 – Concurrent 用户指南--转

    1. java.util.concurrent – Java 并发工具包 Java 5 添加了一个新的包到 Java 平台,java.util.concurrent 包.这个包包含有一系列能够让 Ja ...

  6. Java多线程编程实战指南(核心篇)读书笔记(五)

    (尊重劳动成果,转载请注明出处:http://blog.csdn.net/qq_25827845/article/details/76730459冷血之心的博客) 博主准备恶补一番Java高并发编程相 ...

  7. Java并发指南11:解读 Java 阻塞队列 BlockingQueue

    解读 Java 并发队列 BlockingQueue 转自:https://javadoop.com/post/java-concurrent-queue 最近得空,想写篇文章好好说说 java 线程 ...

  8. JavaScript权威指南 - 函数

    函数本身就是一段JavaScript代码,定义一次但可能被调用任意次.如果函数挂载在一个对象上,作为对象的一个属性,通常这种函数被称作对象的方法.用于初始化一个新创建的对象的函数被称作构造函数. 相对 ...

  9. UE4新手之编程指南

    虚幻引擎4为程序员提供了两套工具集,可共同使用来加速开发的工作流程. 新的游戏类.Slate和Canvas用户接口元素以及编辑器功能可以使用C++语言来编写,并且在使用Visual Studio 或 ...

随机推荐

  1. php中mysqli_error($conn)的用法

    注意:用函数判断sql语句是否有错需要把这个函数写在mysqli_query("$conn连接语句","$sql语句")后面才能进行检测. 返回值:返回最近调用 ...

  2. IDEA使用maven搭建spring项目

    spring框架 Spring框架是由于软件开发的复杂性而创建的.Spring使用的是基本的JavaBean来完成以前只可能由EJB完成的事情.然而,Spring的用途不仅仅限于服务器端的开发.从简单 ...

  3. Linux命令——ethtool

    转自:https://www.cnblogs.com/kelamoyujuzhen/p/10116423.html 参考:9 Linux ethtool Examples to Manipulate ...

  4. router-link路由传参

    router-link传参 [注意] 1.使用params方式传参时,只支持name跳转: 案例如下: 2.使用query传参,注意:两种都支持 案例如下 .

  5. 201871010126 王亚涛 《面向对象程序设计(java)》 第6-7周学习总结

    项目 内容 这个作业属于哪个课程 https://www.cnblogs.com/nwnu-daizh/ 这个作业的要求在哪里 https://www.cnblogs.com/nwnu-daizh/p ...

  6. python27期day04:列表、元组、range、作业题。

    1.for循环套for循环: for i in "abc": for x in "egf: print(x) 结果是:e g f e g f e g f  2.99乘法表 ...

  7. 三层交换机RIP动态路由实验

    一.   实验目的 1.  掌握三层交换机之间通过RIP协议实现网段互通的配置方法. 2.  理解动态实现方式与静态方式的不同 二.   应用环境 当两台三层交换机级联时,为了保证每台交换机上所连接的 ...

  8. 分布式共识算法 (三) Raft算法

    系列目录 分布式共识算法 (一) 背景 分布式共识算法 (二) Paxos算法 分布式共识算法 (三) Raft算法 分布式共识算法 (四) BTF算法 一.引子 1.1 介绍 Raft 是一种为了管 ...

  9. web安全编码Demo

    目录: 1.生成安全随机数 2.密码安全存储 3.文件上传 4.SQL注入 一.生成安全随机数 用于生成会话sessionid.防CSRF时的token.以及其他场景下的veritycode. 如下代 ...

  10. Consul 使用手册(感觉比较全了)

    HTTP API consul的主要接口是RESTful HTTP API,该API可以用来增删查改nodes.services.checks.configguration.所有的endpoints主 ...