博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
Timer与TimerTask之二:timer使用缺陷及用ScheduledThreadPoolExecutor解决
阅读量:6336 次
发布时间:2019-06-22

本文共 5568 字,大约阅读时间需要 18 分钟。

1.缺陷一:Timer由于内部只要一个线程,管理多个任务的时候,一个任务延时,后面的任务就会跟着延时。用下面的例子说明:

package com.dxz.timer;import java.util.Timer;import java.util.TimerTask;public class TimerTaskTest {    private static long startTime;    public static void main(String[] args) {        // 创建一个定时task1        TimerTask task1 = new TimerTask() {            @Override            public void run() {                System.out.println("task1 excude ..." + (System.currentTimeMillis() - startTime));                try {                    Thread.sleep(3000);                } catch (InterruptedException e) {                    e.printStackTrace();                }            }        };        // 创建一个定时task2        TimerTask task2 = new TimerTask() {            @Override            public void run() {                System.out.println("task2 excude ..." + (System.currentTimeMillis() - startTime));                try {                    Thread.sleep(3000);                } catch (InterruptedException e) {                    e.printStackTrace();                }            }        };        Timer timer = new Timer("TimerThread");        startTime = System.currentTimeMillis();        // 第1个任务1s后,执行        timer.schedule(task1, 1000);        // 第2个任务3s后,执行        timer.schedule(task2, 3000);    }}

结果:

task1 excude ...1001task2 excude ...4002

从上面的代码看出,第一个任务1s后执行,第二个任务3s后执行。实际上task2是在4s后才执行的,因为Timer内部是一个线程,而task1所需的时间超过了两个任务的间隔时间导致。下面使用ScheduledThreadPool解决上面的问题:

package com.dxz.timer;import java.util.TimerTask;import java.util.concurrent.Executors;import java.util.concurrent.ScheduledExecutorService;import java.util.concurrent.TimeUnit;public class ScheduledThreadPoolTest1 {    private static long startTime;    public static void main(String[] args) {        ScheduledExecutorService newExecutorService = Executors.newScheduledThreadPool(2);        // 创建一个定时task1        TimerTask task1 = new TimerTask() {            @Override            public void run() {                System.out.println(Thread.currentThread().getName() + " excude ..."                        + (System.currentTimeMillis() - startTime) + "ms");                try {                    Thread.sleep(3000);                } catch (InterruptedException e) {                    e.printStackTrace();                }            }        };        // 创建一个定时task2        TimerTask task2 = new TimerTask() {            @Override            public void run() {                System.out.println(Thread.currentThread().getName() + " excude ..."                        + (System.currentTimeMillis() - startTime) + "ms");                try {                    Thread.sleep(3000);                } catch (InterruptedException e) {                    e.printStackTrace();                }            }        };        startTime = System.currentTimeMillis();        // 第1个任务1000 表示1s后,执行        newExecutorService.schedule(task1, 1000, TimeUnit.MILLISECONDS);        // 第2个任务3000 表示3s后,执行        newExecutorService.schedule(task2, 3000, TimeUnit.MILLISECONDS);    }}

结果:

pool-1-thread-1 excude ...1001mspool-1-thread-2 excude ...3002ms

2、缺陷二:

package com.dxz.timer;import java.util.Date;import java.util.Timer;import java.util.TimerTask;public class TimerTaskTest2 {    private static long startTime;    public static void main(String[] args) {        // 创建一个定时task1        TimerTask task1 = new TimerTask() {            @Override            public void run() {                throw new RuntimeException("运行时异常");            }        };        // 创建一个定时task2        TimerTask task2 = new TimerTask() {            @Override            public void run() {                System.out.println("task2 excude ..." + (System.currentTimeMillis() - startTime));                try {                    Thread.sleep(3000);                } catch (InterruptedException e) {                    e.printStackTrace();                }            }        };        Timer timer = new Timer("TimerThread");        startTime = System.currentTimeMillis();        timer.schedule(task1, 100);        timer.scheduleAtFixedRate(task2, new Date(), 1000);    }}

结果:

task2 excude ...2Exception in thread "TimerThread" java.lang.RuntimeException: 运行时异常    at com.dxz.timer.TimerTaskTest2$1.run(TimerTaskTest2.java:15)    at java.util.TimerThread.mainLoop(Timer.java:555)    at java.util.TimerThread.run(Timer.java:505)

使用ScheduledExecutorService来解决:

package com.dxz.timer;import java.util.TimerTask;import java.util.concurrent.Executors;import java.util.concurrent.ScheduledExecutorService;import java.util.concurrent.TimeUnit;public class ScheduledThreadPoolTest2 {    private static long startTime;    public static void main(String[] args) {        ScheduledExecutorService newExecutorService = Executors.newScheduledThreadPool(1);        // 创建一个定时task1        TimerTask task1 = new TimerTask() {            @Override            public void run() {                new RuntimeException();            }        };        // 创建一个定时task2        TimerTask task2 = new TimerTask() {            @Override            public void run() {                System.out.println(Thread.currentThread().getName() + " excude ..." + (System.currentTimeMillis() - startTime) + "ms");            }        };        startTime = System.currentTimeMillis();        newExecutorService.schedule(task1, 0, TimeUnit.MILLISECONDS);        // 第2个任务3000 表示3s后,执行        newExecutorService.scheduleAtFixedRate(task2,1000, 1000, TimeUnit.MILLISECONDS);    }}

结果:

pool-1-thread-1 excude ...1002mspool-1-thread-1 excude ...2001mspool-1-thread-1 excude ...3002mspool-1-thread-1 excude ...4002ms

 

转载地址:http://gsxoa.baihongyu.com/

你可能感兴趣的文章
64. Minimum Path Sum
查看>>
Windows Live Writer 使用指南
查看>>
分析iOS Crash文件,使用命令符号化iOS Crash文件
查看>>
R学习笔记 第五篇:字符串操作
查看>>
在Mac OS下配置PHP开发环境
查看>>
(转)介绍下Nuget在传统Asp.net项目中的使用
查看>>
C# ArcEngine 实现点击要素高亮并弹出其属性
查看>>
初识GO语言——安装Go语言
查看>>
SDK命令行操作
查看>>
基于Bootstrap的DropDownList的JQuery组件的完善版
查看>>
Hadoop MapReduce编程 API入门系列之分区和合并(十四)
查看>>
并查集的应用之求解无向图中的连接分量个数
查看>>
7个神奇的jQuery 3D插件
查看>>
在线浏览PDF之PDF.JS (附demo)
查看>>
波形捕捉:(3)"捕捉设备"性能
查看>>
AliOS Things lorawanapp应用介绍
查看>>
美国人的网站推广方式千奇百怪
查看>>
java web学习-1
查看>>
用maven+springMVC创建一个项目
查看>>
linux设备驱动第四篇:以oops信息定位代码行为例谈驱动调试方法
查看>>