ScheduledExecutorService和timer的异同
时间:2022-04-25
本文章向大家介绍ScheduledExecutorService和timer的异同,主要内容包括其使用实例、应用技巧、基本知识点总结和需要注意事项,具有一定的参考价值,需要的朋友可以参考一下。
先来个传统的Timer的例子:
package com.jerry.concurrency;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Timer;
import java.util.TimerTask;
public class TraditionalTask {
public static void main(String[] args) throws ParseException {
Timer myTimer = new Timer();
myTimer.schedule(new Worker(), 1000);//1秒后执行
// 2012-02-28 09:58:00执行
myTimer.schedule(new Worker(), new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").parse("2012-02-28 09:58:00"));
myTimer.schedule(new Worker(), 5000,1000);//5秒后执行 每一秒执行一次
// 2012-02-28 09:58:00执行一次 以后每秒执行一次,如果设定的时间点在当前时间之前,任务会被马上执行,然后开始按照设定的周期定时执行任务
myTimer.schedule(new Worker(), new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").parse("2012-02-28 09:58:00"),1000);
myTimer.scheduleAtFixedRate(new Worker(), 5000,1000);//5秒后执行 每一秒执行一次 如果该任务因为某些原因(例如垃圾收集)而延迟执行,那么接下来的任务会尽可能的快速执行,以赶上特定的时间点
myTimer.scheduleAtFixedRate(new Worker(), new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").parse("2012-02-28 09:58:00"),1000);//和上个类似
}
}
class Worker extends TimerTask {
@Override
public void run() {
System.out.println("我被执行了!"+"时间是:"+new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date()));
}
}
传统的timer的缺点:Timer对任务的调度是基于绝对时间的;所有的TimerTask只有一个线程TimerThread来执行,因此同一时刻只有一个TimerTask在执行;任何一个TimerTask的执行异常都会导致Timer终止所有任务;由于基于绝对时间并且是单线程执行,因此在多个任务调度时,长时间执行的任务被执行后有可能导致短时间任务快速在短时间内被执行多次或者干脆丢弃多个任务。
ScheduledExecutorService克服了上述缺点,例子如下:
<span style="font-family:Verdana, Geneva, Arial, Helvetica, sans-serif;font-size:13px;">package com.jerry.concurrency;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;
public class TestScheduledExecutorService{
public static void main(String[] args) throws Exception{
ScheduledExecutorService execService = Executors.newScheduledThreadPool(3);
// 5秒后开始执行 每个2秒执行一次,如果有的任务执行要花费比其周期更长的时间,则将推迟后续执行,但不会同时执行
// 每次相隔相同的时间执行任务,如果任务的执行时间比周期还长,那么下一个任务将立即执行
execService.scheduleAtFixedRate(new Runnable() {
public void run() {
System.out.println("任务:"+Thread.currentThread().getName()+" 执行了,时间为: "+System.currentTimeMillis());
try {
Thread.sleep(1000L);
} catch (Exception e) {
e.printStackTrace();
}
}
}, 5, 2, TimeUnit.SECONDS);
//5秒后开始执行 每个2秒执行一次,保证固定的延迟为2秒 下一个任务的开始时间与上一个任务的结束时间间隔相同
execService.scheduleWithFixedDelay(new Runnable() {
public void run() {
System.out.println("任务:"+Thread.currentThread().getName()+"执行了,时间为:"+System.currentTimeMillis());
try {
Thread.sleep(1000L);
} catch (Exception e) {
e.printStackTrace();
}
}
}, 5, 2, TimeUnit.SECONDS);
Thread.sleep(10000L);
execService.shutdown();
}
}
</span>
- JavaScript 教程
- JavaScript 编辑工具
- JavaScript 与HTML
- JavaScript 与Java
- JavaScript 数据结构
- JavaScript 基本数据类型
- JavaScript 特殊数据类型
- JavaScript 运算符
- JavaScript typeof 运算符
- JavaScript 表达式
- JavaScript 类型转换
- JavaScript 基本语法
- JavaScript 注释
- Javascript 基本处理流程
- Javascript 选择结构
- Javascript if 语句
- Javascript if 语句的嵌套
- Javascript switch 语句
- Javascript 循环结构
- Javascript 循环结构实例
- Javascript 跳转语句
- Javascript 控制语句总结
- Javascript 函数介绍
- Javascript 函数的定义
- Javascript 函数调用
- Javascript 几种特殊的函数
- JavaScript 内置函数简介
- Javascript eval() 函数
- Javascript isFinite() 函数
- Javascript isNaN() 函数
- parseInt() 与 parseFloat()
- escape() 与 unescape()
- Javascript 字符串介绍
- Javascript length属性
- javascript 字符串函数
- Javascript 日期对象简介
- Javascript 日期对象用途
- Date 对象属性和方法
- Javascript 数组是什么
- Javascript 创建数组
- Javascript 数组赋值与取值
- Javascript 数组属性和方法
- 深入探究JVM之类加载与双亲委派机制
- 深入探究JVM之方法调用及Lambda表达式实现原理
- synchronized的实现原理——对象头解密
- Golang 汇编入门知识总结
- C语言小笔记(1)
- 这一次搞懂Spring的XML解析原理
- 这一次搞懂Spring自定义标签以及注解解析原理
- 这一次搞懂Spring的Bean实例化原理
- 单片机入门学习十三 STM32单片机学习十 通用定时器
- Spring IOC原理补充(循环依赖、Bean作用域等)
- 这一次搞懂Spring代理创建及AOP链式调用过程
- 这一次搞懂Spring事务注解的解析
- 这一次搞懂Spring事务是如何传播的
- 这一次搞懂SpringMVC原理
- 这一次搞懂Spring Web零xml配置原理以及父子容器关系