先来个传统的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. [HNOI2009]无归岛

    Description Neverland是个神奇的地方,它由一些岛屿环形排列组成,每个岛上都生活着之中与众不同的物种.但是这些物种都有一个共同的生活习性:对于同一个岛上的任意两个生物,他们有且仅有一 ...

  2. [USACO15OPEN]回文的路径Palindromic Paths 2.0版

    题目描述 农夫FJ的农场是一个N*N的正方形矩阵(2\le N\le 5002≤N≤500),每一块用一个字母作标记.比如说: ABCD BXZX CDXB WCBA 某一天,FJ从农场的左上角走到右 ...

  3. TopCoder SRM 560 Div 1 - Problem 1000 BoundedOptimization & Codeforces 839 E

    传送门:https://284914869.github.io/AEoj/560.html 题目简述: 定义"项"为两个不同变量相乘. 求一个由多个不同"项"相 ...

  4. hdu 4514 并查集+树形dp

    湫湫系列故事——设计风景线 Time Limit: 6000/3000 MS (Java/Others)    Memory Limit: 65535/32768 K (Java/Others)Tot ...

  5. 2015 多校联赛 ——HDU5302(构造)

    Connect the Graph Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others ...

  6. hdu 4288 离线线段树+间隔求和

    Coder Time Limit: 20000/10000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Total Su ...

  7. splay模板(BZOJ3224)

    用splay实现二叉搜索树的模板,支持插入,删除,找前缀后缀,x的排名以及第x名的数. #include <cstdio> #define l(x) t[x].s[0] #define r ...

  8. CentOS7.4 源码安装MySQL8.0

    MySQL 8 正式版 8.0.11 已发布,官方表示 MySQL 8 要比 MySQL 5.7 快 2 倍,还带来了大量的改进和更快的性能! 以下为本人2018.4.23日安装过程的记录.整个过程大 ...

  9. java开发小技巧

    链接地址:http://www.cnblogs.com/zkh101/p/8083368.html 人脸识别地址:http://blog.csdn.net/gitchat/article/detail ...

  10. java如何获得数据库表中各字段的字段名

    public class TestDemo { public static Connection getConnection() { Connection conn = null; try { Cla ...