java中timer与thread,Java中Timer和ThreadPoolExecutor的区别和比较

今天闲来无事读Java中Timer的源码,发现Timer的注释中有这么一段

Java 5.0 introduced the {@code java.util.concurrent} package and

one of the concurrency utilities therein is the {@link

java.util.concurrent.ScheduledThreadPoolExecutor

ScheduledThreadPoolExecutor} which is a thread pool for repeatedly

executing tasks at a given rate or delay. It is effectively a more

versatile replacement for the {@code Timer}/{@code TimerTask}

combination, as it allows multiple service threads, accepts various

time units, and doesn’t require subclassing {@code TimerTask} (just

implement {@code Runnable}). Configuring {@code

ScheduledThreadPoolExecutor} with one thread makes it equivalent to

{@code Timer}.

其大意是说Timer的API有单线程的问题,一个定时器不允许同时执行任务。官方说在JDK1.5之后引入了ScheduledThreadPoolExecutor类来实现多线程的定时器。那就来看看到底是怎么回事把。

Timer

package com.freud.test;

import java.util.Date;

import java.util.Timer;

import java.util.TimerTask;

public class TimerTest {

private static long start = System.currentTimeMillis();

public static void main(String[] args) {

Timer timer = new Timer();

timer.scheduleAtFixedRate(new TimerTask() {

@Override

public void run() {

try {

System.out.println("Timer 1 start at:"

+ (System.currentTimeMillis() - start));

Thread.sleep(1000);

System.out.println("Timer 1 finish at:"

+ (System.currentTimeMillis() - start));

// throw new RuntimeException("Exception occured here!");

} catch (InterruptedException e) {

System.out.println("Thread was interrupted.");

}

}

}, new Date(), 1000);

timer.scheduleAtFixedRate(new TimerTask() {

@Override

public void run() {

try {

System.out.println("Timer 2 start at:"

+ (System.currentTimeMillis() - start));

Thread.sleep(1000);

System.out.println("Timer 2 finish at:"

+ (System.currentTimeMillis() - start));

} catch (InterruptedException e) {

System.out.println("Thread was interrupted.");

}

}

}, new Date(), 1000);

}

}

执行上述代码后会发现打印输出如下:

Timer 1 start at:1

Timer 1 finish at:1001

Timer 2 start at:1001

Timer 2 finish at:2001

Timer 2 start at:2001

Timer 2 finish at:3001

Timer 1 start at:3001

Timer 1 finish at:4001

Timer 1 start at:4001

Timer 1 finish at:5001

Timer 2 start at:5001

Timer 2 finish at:6002

Timer 2 start at:6002

Timer 2 finish at:7002

Timer 1 start at:7002

Timer 1 finish at:8002

Timer 1 start at:8002

Timer 1 finish at:9002

Timer 2 start at:9002

Timer 2 finish at:10002

Timer 2 start at:10002

Timer 2 finish at:11002

Timer 1 start at:11002

通过日志不难看出,在一个Timer中的2个TimerTask是有执行顺序的,也就是上一个没有执行完,下一个是不会触发的。而究其原因,看源码发现Timer的实现中只有一个TimerThread线程通过while (true)的loop来执行存储在TaskQueue中的定时器任务

public class Timer {

/**

* The timer task queue. This data structure is shared with the timer

* thread. The timer produces tasks, via its various schedule calls,

* and the timer thread consumes, executing timer tasks as appropriate,

* and removing them from the queue when they're obsolete.

*/

private final TaskQueue queue = new TaskQueue();

/**

* The timer thread.

*/

private final TimerThread thread = new TimerThread(queue);

并且在loop的过程中只捕获了InterruptedException导致其中一个Task出现错误,会影响接下来的所有Task的执行。

/**

* The main timer loop. (See class comment.)

*/

private void mainLoop() {

while (true) {

try {

//*****

if (taskFired) // Task fired; run it, holding no locks

task.run();

} catch(InterruptedException e) {

}

}

}

打开TimerTest中注释掉的throw new RuntimeException("Exception occured here!");代码,会发现Task2不会执行!

ScheduledThreadPoolExecutor

package com.freud.test;

import java.util.concurrent.Executors;

import java.util.concurrent.ScheduledExecutorService;

import java.util.concurrent.TimeUnit;

public class ScheduledThreadPoolExecutorTest {

private static long start = System.currentTimeMillis();

public static void main(String[] args) {

ScheduledExecutorService schedule = Executors.newScheduledThreadPool(1);

schedule.scheduleAtFixedRate(new Runnable() {

@Override

public void run() {

try {

System.out.println("Schedule 1 start at:"

+ (System.currentTimeMillis() - start));

Thread.sleep(1000);

System.out.println("Schedule 1 finish at:"

+ (System.currentTimeMillis() - start));

// throw new RuntimeException("Exception occured here!");

} catch (InterruptedException e) {

System.out.println("Thread was interrupted.");

}

}

}, 1, 1, TimeUnit.SECONDS);

schedule.scheduleAtFixedRate(new Runnable() {

@Override

public void run() {

try {

System.out.println("Schedule 2 start at:"

+ (System.currentTimeMillis() - start));

Thread.sleep(1000);

System.out.println("Schedule 2 finish at:"

+ (System.currentTimeMillis() - start));

} catch (InterruptedException e) {

System.out.println("Thread was interrupted.");

}

}

}, 1, 1, TimeUnit.SECONDS);

}

}

观察到的结果如下,可以发现是跟Timer的执行结果是一样的.

Schedule 1 start at:1003

Schedule 1 finish at:2004

Schedule 2 start at:2004

Schedule 2 finish at:3004

Schedule 1 start at:3004

Schedule 1 finish at:4004

Schedule 2 start at:4004

Schedule 2 finish at:5004

Schedule 1 start at:5004

Schedule 1 finish at:6004

Schedule 2 start at:6004

Schedule 2 finish at:7004

Schedule 1 start at:7004

此时,修改Executors.newScheduledThreadPool(1)为Executors.newScheduledThreadPool(2)创建两个线程来执行定时器任务,观察到结果预期应该是每秒钟2个任务同时执行,结果如下,符合预期。

Schedule 1 start at:1004

Schedule 2 start at:1004

Schedule 2 finish at:2005

Schedule 1 finish at:2005

Schedule 2 start at:2005

Schedule 1 start at:2005

Schedule 1 finish at:3005

Schedule 1 start at:3005

Schedule 2 finish at:3009

Schedule 2 start at:3009

Schedule 1 finish at:4005

Schedule 1 start at:4005

Schedule 2 finish at:4009

Schedule 2 start at:4009

当打开throw new RuntimeException("Exception occured here!");之后会发现Schedule2正常执行,Schedule1的异常不会影响Schedule2的执行!

Schedule 1 start at:1003

Schedule 2 start at:1004

Schedule 1 finish at:2004

Schedule 2 finish at:2004

Schedule 2 start at:2004

Schedule 2 finish at:3004

Schedule 2 start at:3004

Schedule 2 finish at:4004

Schedule 2 start at:4004

Schedule 2 finish at:5004

Schedule 2 start at:5004

Schedule 2 finish at:6004

Schedule 2 start at:6004

结论

Timer可以做的事情,通过ScheduledThreadPoolExecutor都可以做到,并且修复了其中Timer的部分设计上的缺陷。并且实现了多线程的执行,相对来说功能是比Timer强大了一个等级。

Java中Timer和ThreadPoolExecutor学习比较系列文章:

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
智慧校园整体解决方案是响应国家教育信息化政策,结合教育改革和技术创新的产物。该方案以物联网、大数据、人工智能和移动互联技术为基础,旨在打造一个安全、高效、互动且环保的教育环境。方案强调从数字化校园向智慧校园的转变,通过自动数据采集、智能分析和按需服务,实现校园业务的智能化管理。 方案的总体设计原则包括应用至上、分层设计和互联互通,确保系统能够满足不同用户角色的需求,并实现数据和资源的整合与共享。框架设计涵盖了校园安全、管理、教学、环境等多个方面,构建了一个全面的校园应用生态系统。这包括智慧安全系统、校园身份识别、智能排课及选课系统、智慧学习系统、精品录播教室方案等,以支持个性化学习和教学评估。 建设内容突出了智慧安全和智慧管理的重要性。智慧安全管理通过分布式录播系统和紧急预案一键启动功能,增强校园安全预警和事件响应能力。智慧管理系统则利用物联网技术,实现人员和设备的智能管理,提高校园运营效率。 智慧教学部分,方案提供了智慧学习系统和精品录播教室方案,支持专业级学习硬件和智能化网络管理,促进个性化学习和教学资源的高效利用。同时,教学质量评估心和资源应用平台的建设,旨在提升教学评估的科学性和教育资源的共享性。 智慧环境建设则侧重于基于物联网的设备管理,通过智慧教室管理系统实现教室环境的智能控制和能效管理,打造绿色、节能的校园环境。电子班牌和校园信息发布系统的建设,将作为智慧校园的核心和入口,提供教务、一卡通、图书馆等系统的集成信息。 总体而言,智慧校园整体解决方案通过集成先进技术,不仅提升了校园的信息化水平,而且优化了教学和管理流程,为学生、教师和家长提供了更加便捷、个性化的教育体验。
org.apache.catalina.core.StandardContext.listenerStart Exception sending context initialized event to listener instance of class [com.freshlife.willtech.chatkernel.timer.NFDFlightDataTaskListener] java.lang.NoClassDefFoundError: com/fasterxml/jackson/core/JsonProcessingException at com.freshlife.willtech.chatkernel.timer.NFDFlightDataTaskListener.contextInitialized(NFDFlightDataTaskListener.java:45) at org.apache.catalina.core.StandardContext.listenerStart(StandardContext.java:4792) at org.apache.catalina.core.StandardContext.startInternal(StandardContext.java:5256) at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:150) at org.apache.catalina.core.ContainerBase.addChildInternal(ContainerBase.java:754) at org.apache.catalina.core.ContainerBase.addChild(ContainerBase.java:730) at org.apache.catalina.core.StandardHost.addChild(StandardHost.java:734) at org.apache.catalina.startup.HostConfig.deployWAR(HostConfig.java:985) at org.apache.catalina.startup.HostConfig$DeployWar.run(HostConfig.java:1857) at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:511) at java.util.concurrent.FutureTask.run(FutureTask.java:266) at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142) at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617) at java.lang.Thread.run(Thread.java:748) Caused by: java.lang.ClassNotFoundException: com.fasterxml.jackson.core.JsonProcessingException at org.apache.catalina.loader.WebappClassLoaderBase.loadClass(WebappClassLoaderBase.java:1308) at org.apache.catalina.loader.WebappClassLoaderBase.loadClass(WebappClassLoaderBase.java:1136) ... 14 more
06-10
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值