先来个传统的Timer的例子:

  1. package com.jerry.concurrency;
  2. import java.text.ParseException;
  3. import java.text.SimpleDateFormat;
  4. import java.util.Date;
  5. import java.util.Timer;
  6. import java.util.TimerTask;
  7. public class TraditionalTask {
  8. public static void main(String[] args) throws ParseException {
  9. Timer myTimer = new Timer();
  10. myTimer.schedule(new Worker(), 1000);//1秒后执行
  11. //      2012-02-28 09:58:00执行
  12. myTimer.schedule(new Worker(), new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").parse("2012-02-28 09:58:00"));
  13. myTimer.schedule(new Worker(), 5000,1000);//5秒后执行 每一秒执行一次
  14. //      2012-02-28 09:58:00执行一次 以后每秒执行一次,如果设定的时间点在当前时间之前,任务会被马上执行,然后开始按照设定的周期定时执行任务
  15. myTimer.schedule(new Worker(), new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").parse("2012-02-28 09:58:00"),1000);
  16. myTimer.scheduleAtFixedRate(new Worker(), 5000,1000);//5秒后执行 每一秒执行一次 如果该任务因为某些原因(例如垃圾收集)而延迟执行,那么接下来的任务会尽可能的快速执行,以赶上特定的时间点
  17. myTimer.scheduleAtFixedRate(new Worker(), new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").parse("2012-02-28 09:58:00"),1000);//和上个类似
  18. }
  19. }
  20. class Worker extends TimerTask {
  21. @Override
  22. public void run() {
  23. System.out.println("我被执行了!"+"时间是:"+new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date()));
  24. }
  25. }

传统的timer的缺点:Timer对任务的调度是基于绝对时间的;所有的TimerTask只有一个线程TimerThread来执行,因此同一时刻只有一个TimerTask在执行;任何一个TimerTask的执行异常都会导致Timer终止所有任务;由于基于绝对时间并且是单线程执行,因此在多个任务调度时,长时间执行的任务被执行后有可能导致短时间任务快速在短时间内被执行多次或者干脆丢弃多个任务。

ScheduledExecutorService克服了上述缺点,例子如下:

  1. <span style="font-family:Verdana, Geneva, Arial, Helvetica, sans-serif;font-size:13px;">package com.jerry.concurrency;
  2. import java.util.concurrent.Executors;
  3. import java.util.concurrent.ScheduledExecutorService;
  4. import java.util.concurrent.TimeUnit;
  5. public class TestScheduledExecutorService{
  6. public static void main(String[] args) throws Exception{
  7. ScheduledExecutorService execService =   Executors.newScheduledThreadPool(3);
  8. // 5秒后开始执行 每个2秒执行一次,如果有的任务执行要花费比其周期更长的时间,则将推迟后续执行,但不会同时执行
  9. //        每次相隔相同的时间执行任务,如果任务的执行时间比周期还长,那么下一个任务将立即执行
  10. execService.scheduleAtFixedRate(new Runnable() {
  11. public void run() {
  12. System.out.println("任务:"+Thread.currentThread().getName()+" 执行了,时间为: "+System.currentTimeMillis());
  13. try {
  14. Thread.sleep(1000L);
  15. } catch (Exception e) {
  16. e.printStackTrace();
  17. }
  18. }
  19. }, 5, 2, TimeUnit.SECONDS);
  20. //5秒后开始执行 每个2秒执行一次,保证固定的延迟为2秒 下一个任务的开始时间与上一个任务的结束时间间隔相同
  21. execService.scheduleWithFixedDelay(new Runnable() {
  22. public void run() {
  23. System.out.println("任务:"+Thread.currentThread().getName()+"执行了,时间为:"+System.currentTimeMillis());
  24. try {
  25. Thread.sleep(1000L);
  26. } catch (Exception e) {
  27. e.printStackTrace();
  28. }
  29. }
  30. }, 5, 2, TimeUnit.SECONDS);
  31. Thread.sleep(10000L);
  32. execService.shutdown();
  33. }
  34. }
  35. </span>

ScheduledExecutorService和timer的异同的更多相关文章

  1. 使用ScheduledExecutorService实现Timer

    大家都说Timer不太好用,经常会遇到:如果前边的一个任务比较慢,超出了period,此时timer的下一次轮询也会延迟. 同事说ScheduleExecutorService可以避免该问题,我写个例 ...

  2. 任务调度(四)——ScheduledExecutorService替代Timer,实现多线程任务调度

    上篇博文<任务调度(三)--Timer的替代品ScheduledExecutorService简介>已经对ScheduledExecutorService做了简介.事实上使用Schedul ...

  3. java定时任务Timer与ScheduledExecutorService<转>

    在我们编程过程中如果需要执行一些简单的定时任务,无须做复杂的控制,我们可以考虑使用JDK中的Timer定时任务来实现.下面LZ就其原理.实例以及Timer缺陷三个方面来解析java Timer定时器. ...

  4. 详解java定时任务---Timer篇

    一.简介      在java的jdk中提供了Timer.TimerTask两个类来做定时任务. Timer是一种定时器工具,用来在一个后台线程计划执行指定任务,而TimerTask一个抽象类,它的子 ...

  5. 线程 Timer TimerTask 计时器 定时任务 MD

    Markdown版本笔记 我的GitHub首页 我的博客 我的微信 我的邮箱 MyAndroidBlogs baiqiantao baiqiantao bqt20094 baiqiantao@sina ...

  6. 详解java定时任务

    在我们编程过程中如果需要执行一些简单的定时任务,无须做复杂的控制,我们可以考虑使用JDK中的Timer定时任务来实现.下面LZ就其原理.实例以及Timer缺陷三个方面来解析JavaTimer定时器. ...

  7. Java 四种线程池newCachedThreadPool,newFixedThreadPool,newScheduledThreadPool,newSingleThreadExecutor

    介绍new Thread的弊端及Java四种线程池的使用,对Android同样适用.本文是基础篇,后面会分享下线程池一些高级功能. 1.new Thread的弊端执行一个异步任务你还只是如下new T ...

  8. Java四种线程池

    Java四种线程池newCachedThreadPool,newFixedThreadPool,newScheduledThreadPool,newSingleThreadExecutor 时间:20 ...

  9. Java(Android)线程池

      1.new Thread的弊端执行一个异步任务你还只是如下new Thread吗? new Thread(new Runnable() { @Override public void run()  ...

随机推荐

  1. SAC E#1 - 一道中档题 Factorial

    题目背景 SOL君(炉石主播)和SOL菌(完美信息教室讲师)是好朋友. 题目描述 SOL君很喜欢阶乘.而SOL菌很喜欢研究进制. 这一天,SOL君跟SOL菌炫技,随口算出了n的阶乘. SOL菌表示不服 ...

  2. 紧急疏散evacuate

    1689: [HNOI2007]紧急疏散evacuate 题目描述 发生了火警,所有人员需要紧急疏散!假设每个房间是一个N M的矩形区域.每个格子如果是".",那么表示这是一块空地 ...

  3. ●UVa 11346 Probability

    题链: https://vjudge.net/problem/UVA-11346题解: 连续概率,积分 由于对称性,我们只用考虑第一象限即可. 如果要使得面积大于S,即xy>S, 那么可以选取的 ...

  4. hdu4542 && ZOJ2562(反素数)

    反素数: 对于任何正整数,其约数个数记为,例如,如果某个正整数满足:对任意的正整 数,都有,那么称为反素数. 有两个特点: 1.一个反素数的质因子必是从2开始的质数 2.如果,那么必有 最常见的问题如 ...

  5. bzoj1096[ZJOI2007]仓库建设 斜率优化dp

    1096: [ZJOI2007]仓库建设 Time Limit: 10 Sec  Memory Limit: 162 MBSubmit: 5482  Solved: 2448[Submit][Stat ...

  6. Python中的文件路径的分隔符

    主要是需要考虑分隔符的问题: 在Windows系统下的分隔符是:\ (反斜杠). 在Linux系统下的分隔符是:/(斜杠). 当在字符中出现\时,大家就要考虑到转义字符了. 转义字符的概念,参考维基百 ...

  7. vrn:基于直接体积回归的单幅图像大姿态三维人脸重建

    3D面部重建是一个非常困难的基本计算机视觉问题.目前的系统通常假设多个面部图像(有时来自同一主题)作为输入的可用性,并且必须解决许多方法学挑战,例如在大的面部姿势,表情和不均匀照明之间建立密集的对应. ...

  8. button点击切换,获取按钮ID

    <!DOCTYPE html> <html> <head lang="zh-CN"> <meta charset="UTF-8& ...

  9. request.url 端口 错误

    今天遇到一个很奇怪的事情,用request.url.port来获取一个请求的端口,返回是80 ,很纳闷啊我的请求上面是http://www.XX.com:8088 啊,怎么会是80啊,太不可思议了! ...

  10. mongo索引

    索引自动创建和手工创建 db.stu.drop(); db.stu.insert({"name":"张三","sex":"男&qu ...