GIT: https://github.com/whtchl/JavaConcurrentTemplate

继续并发,上篇博客对于ScheduledThreadPoolExecutor没有进行介绍,说过会和Timer一直单独写一篇Blog.

1、Timer管理延时任务的缺陷

a、以前在项目中也经常使用定时器,比如每隔一段时间清理项目中的一些垃圾文件,每个一段时间进行数据清洗;然而Timer是存在一些缺陷的,因为Timer在执行定时任务时只会创建一个线程,所以如果存在多个任务,且任务时间过长,超过了两个任务的间隔时间,会发生一些缺陷:下面看例子:

Timer的源码:

[java] view plain copy
  1. public class Timer {
  2. /**
  3. * The timer task queue.  This data structure is shared with the timer
  4. * thread.  The timer produces tasks, via its various schedule calls,
  5. * and the timer thread consumes, executing timer tasks as appropriate,
  6. * and removing them from the queue when they're obsolete.
  7. */
  8. private TaskQueue queue = new TaskQueue();
  9. /**
  10. * The timer thread.
  11. */
  12. private TimerThread thread = new TimerThread(queue);

TimerThread是Thread的子类,可以看出内部只有一个线程。下面看个例子:

[java] view plain copy
  1. package com.zhy.concurrency.timer;
  2. import java.util.Timer;
  3. import java.util.TimerTask;
  4. public class TimerTest
  5. {
  6. private static long start;
  7. public static void main(String[] args) throws Exception
  8. {
  9. TimerTask task1 = new TimerTask()
  10. {
  11. @Override
  12. public void run()
  13. {
  14. System.out.println("task1 invoked ! "
  15. + (System.currentTimeMillis() - start));
  16. try
  17. {
  18. Thread.sleep(3000);
  19. } catch (InterruptedException e)
  20. {
  21. e.printStackTrace();
  22. }
  23. }
  24. };
  25. TimerTask task2 = new TimerTask()
  26. {
  27. @Override
  28. public void run()
  29. {
  30. System.out.println("task2 invoked ! "
  31. + (System.currentTimeMillis() - start));
  32. }
  33. };
  34. Timer timer = new Timer();
  35. start = System.currentTimeMillis();
  36. timer.schedule(task1, 1000);
  37. timer.schedule(task2, 3000);
  38. }
  39. }

定义了两个任务,预计是第一个任务1s后执行,第二个任务3s后执行,但是看运行结果:

[java] view plain copy
  1. task1 invoked ! 1000
  2. task2 invoked ! 4000

task2实际上是4后才执行,正因为Timer内部是一个线程,而任务1所需的时间超过了两个任务间的间隔导致。下面使用ScheduledThreadPool解决这个问题:

[java] view plain copy
  1. package com.zhy.concurrency.timer;
  2. import java.util.TimerTask;
  3. import java.util.concurrent.Executors;
  4. import java.util.concurrent.ScheduledExecutorService;
  5. import java.util.concurrent.TimeUnit;
  6. public class ScheduledThreadPoolExecutorTest
  7. {
  8. private static long start;
  9. public static void main(String[] args)
  10. {
  11. /**
  12. * 使用工厂方法初始化一个ScheduledThreadPool
  13. */
  14. ScheduledExecutorService newScheduledThreadPool = Executors
  15. .newScheduledThreadPool(2);
  16. TimerTask task1 = new TimerTask()
  17. {
  18. @Override
  19. public void run()
  20. {
  21. try
  22. {
  23. System.out.println("task1 invoked ! "
  24. + (System.currentTimeMillis() - start));
  25. Thread.sleep(3000);
  26. } catch (Exception e)
  27. {
  28. e.printStackTrace();
  29. }
  30. }
  31. };
  32. TimerTask task2 = new TimerTask()
  33. {
  34. @Override
  35. public void run()
  36. {
  37. System.out.println("task2 invoked ! "
  38. + (System.currentTimeMillis() - start));
  39. }
  40. };
  41. start = System.currentTimeMillis();
  42. newScheduledThreadPool.schedule(task1, 1000, TimeUnit.MILLISECONDS);
  43. newScheduledThreadPool.schedule(task2, 3000, TimeUnit.MILLISECONDS);
  44. }
  45. }

输出结果:

[java] view plain copy
  1. task1 invoked ! 1001
  2. task2 invoked ! 3001

符合我们的预期结果。因为ScheduledThreadPool内部是个线程池,所以可以支持多个任务并发执行。

2、Timer当任务抛出异常时的缺陷

如果TimerTask抛出RuntimeException,Timer会停止所有任务的运行:

[java] view plain copy
  1. package com.zhy.concurrency.timer;
  2. import java.util.Date;
  3. import java.util.Timer;
  4. import java.util.TimerTask;
  5. public class ScheduledThreadPoolDemo01
  6. {
  7. public static void main(String[] args) throws InterruptedException
  8. {
  9. final TimerTask task1 = new TimerTask()
  10. {
  11. @Override
  12. public void run()
  13. {
  14. throw new RuntimeException();
  15. }
  16. };
  17. final TimerTask task2 = new TimerTask()
  18. {
  19. @Override
  20. public void run()
  21. {
  22. System.out.println("task2 invoked!");
  23. }
  24. };
  25. Timer timer = new Timer();
  26. timer.schedule(task1, 100);
  27. timer.scheduleAtFixedRate(task2, new Date(), 1000);
  28. }
  29. }

上面有两个任务,任务1抛出一个运行时的异常,任务2周期性的执行某个操作,输出结果:

[java] view plain copy
  1. task2 invoked!
  2. Exception in thread "Timer-0" java.lang.RuntimeException
  3. at com.zhy.concurrency.timer.ScheduledThreadPoolDemo01$1.run(ScheduledThreadPoolDemo01.java:24)
  4. at java.util.TimerThread.mainLoop(Timer.java:512)
  5. at java.util.TimerThread.run(Timer.java:462)

由于任务1的一次,任务2也停止运行了。。。下面使用ScheduledExecutorService解决这个问题:

[java] view plain copy
  1. package com.zhy.concurrency.timer;
  2. import java.util.Date;
  3. import java.util.Timer;
  4. import java.util.TimerTask;
  5. import java.util.concurrent.Executors;
  6. import java.util.concurrent.ScheduledExecutorService;
  7. import java.util.concurrent.TimeUnit;
  8. public class ScheduledThreadPoolDemo01
  9. {
  10. public static void main(String[] args) throws InterruptedException
  11. {
  12. final TimerTask task1 = new TimerTask()
  13. {
  14. @Override
  15. public void run()
  16. {
  17. throw new RuntimeException();
  18. }
  19. };
  20. final TimerTask task2 = new TimerTask()
  21. {
  22. @Override
  23. public void run()
  24. {
  25. System.out.println("task2 invoked!");
  26. }
  27. };
  28. ScheduledExecutorService pool = Executors.newScheduledThreadPool(1);
  29. pool.schedule(task1, 100, TimeUnit.MILLISECONDS);
  30. pool.scheduleAtFixedRate(task2, 0 , 1000, TimeUnit.MILLISECONDS);
  31. }
  32. }

代码基本一致,但是ScheduledExecutorService可以保证,task1出现异常时,不影响task2的运行:

[java] view plain copy
  1. task2 invoked!
  2. task2 invoked!
  3. task2 invoked!
  4. task2 invoked!
  5. task2 invoked!<span style="font-family: Arial, Helvetica, sans-serif;">...</span>

3、Timer执行周期任务时依赖系统时间

Timer执行周期任务时依赖系统时间,如果当前系统时间发生变化会出现一些执行上的变化,ScheduledExecutorService基于时间的延迟,不会由于系统时间的改变发生执行变化。

上述,基本说明了在以后的开发中尽可能使用ScheduledExecutorService(JDK1.5以后)替代Timer。

Timer的缺陷 用ScheduledExecutorService替代相关推荐

  1. 使用Timer的缺陷

    2019独角兽企业重金招聘Python工程师标准>>> Java.util.Timer定时器实际上是一个单线程,实际调度所拥有的TimerTask任务. 1.时间的不准确性 如果存在 ...

  2. Java SE加强篇——超详细,Java入门,这一篇就够了

    建议先阅读 JavaSE基础篇 第一天:面向对象进阶一 一.static静态 关键字 1.static是什么? static是静态的意思,可以修饰成员变量和成员方法 static修饰成员变量表示该成员 ...

  3. day16多线程网络编程日志枚举

    多线程&网络编程 一.实现多线程 1.1 相关概念 线程是操作系统能够进行运算调度的最小单位.它被包含在进程之中,是进程中的一条执行路径.实际运作单位.简单理解:应用软件中互相独立,可以同时运 ...

  4. java捕获定时器抛出的异常_详细了解Java中定时器Timer的使用及缺陷分析

    在需要定时并且周期执行任务时,在最初的JAVA工具类库中,Timer可以实现任务的定时周期执行的需求,不过有一定的缺陷,比如,Timer是基于绝对时间而非相对时间,因此Timer对系统时钟比较敏感,本 ...

  5. java一定时间间隔的定时任务_Java 定时任务---Timer

    本文来自我一个朋友的个人博客(希望各位以后多多支持):https://www.liupeng.mobi/archives/777 一.Timer类 在java中一个完整的定时任务需要由Timer和Ti ...

  6. 为什么你不该用Timer

    概述 在Java开发中,用过定时功能的同学一定不会对Timer感到陌生.不过,除了Timer,在Java 5之后又引入了一个定时工具ScheduledThreadPoolExecutor,那么我们应该 ...

  7. 【Java定时任务调度工具】Timer

    笔记来源:IMOOC Java Timer 定时任务调度 基于给定的时间点,给定的时间间隔或者给定的执行次数自动执行的任务. Timer 定义 一种工具,线程用其安排以后在后台线程中执行的任务.可安排 ...

  8. 缺陷预防-我认为的质量改进正道之光

    欢迎关注公众号"软件质量奇谈".关于软件工程,测试,质量管理等问题,欢迎在公众号留言提问,必定尽力解答,如有资料需求,也可尽力分享. 前段时间在和几位研发团队负责人讨论团队的质量目 ...

  9. 【慕课笔记】Java定时任务调度工具详解之Timer篇_0理论

    慕课地址 1 简单介绍 1)什么是定时任务调度 2)Timer简介 打开jdk-zh说明文档查看即可 推荐看英文版本的 简单写个demo,感受一下timer的定时调度函数.schedule()(本人实 ...

最新文章

  1. ECS服务器指定实例规格最佳推荐
  2. linux 守护进程管理 supervisor 简介 可用于docker容器内守护进程
  3. PHP获取当前时间、时间戳的各种格式写法汇总[日期时间]
  4. mysql修改字符集utf8为utf8mb4
  5. 超基础的Android studio的安装教程
  6. linux 安装软件
  7. 技术分享 | 一文带你了解测试流程体系
  8. i.mx6 linux 占用率,i.MX6UL在Linux和Windows平台下SD启动卡测试步骤
  9. 黑客X档案的《黑客免杀入门》
  10. linux 上传下载测速
  11. 《不只是美:信息图表设计原理与经典案例》—— 2.7 更加灵活
  12. 快速给图片加水印的方法
  13. 基于大型数字视频监控系统解决方案
  14. 【Python】把excel文件中的数据转化为字典格式存起来
  15. 嵌入式系统python开发_嵌组词_嵌的拼音含义_组词造句解释_嵌字的组词
  16. VR/AR年度创投报告
  17. 帮你学会webpack
  18. solidity部署和验证代理合约
  19. php单独使用laravel数据库 | laravel手动关闭数据库连接
  20. TrueNAS安装(虚拟机环境)

热门文章

  1. php 模板使用,在PHP中使用模板的方法
  2. C++知识点21——使用C++标准库(再谈string——string的搜索和数值转化)
  3. 本质矩阵与基本矩阵(对极几何)
  4. skipping non-radio button in group解决方法
  5. AprilTag中的g3d.h和g2d.c文件
  6. python提供两个对象身份比较操作符什么和什么来测试_python - 第二部分
  7. jmeter操作数据库
  8. 因缺失log4j.properties 配置文件导致flume无法正常启动。
  9. ApiCloud云端管理平台(v.20151022)
  10. FZU 2159 WuYou