JDK 1.5开始提供ScheduledThreadPoolExecutor类,ScheduledThreadPoolExecutor类继承ThreadPoolExecutor类重用线程池实现了工作的周期性调度性能。在JDK 1.5之前,实现工作的周期性调度次要应用的是Timer类和TimerTask类。本文,就简略介绍下ScheduledThreadPoolExecutor类与Timer类的区别,ScheduledThreadPoolExecutor类相比于Timer类来说,到底有哪些劣势,以及二者别离实现任务调度的简略示例。
二者的区别
线程角度
- Timer是单线程模式,如果某个TimerTask工作的执行工夫比拟久,会影响到其余工作的调度执行。
- ScheduledThreadPoolExecutor是多线程模式,并且重用线程池,某个ScheduledFutureTask工作执行的工夫比拟久,不会影响到其余工作的调度执行。
零碎工夫敏感度
- Timer调度是基于操作系统的相对工夫的,对操作系统的工夫敏感,一旦操作系统的工夫扭转,则Timer的调度不再准确。
- ScheduledThreadPoolExecutor调度是基于绝对工夫的,不受操作系统工夫扭转的影响。
是否捕捉异样
- Timer不会捕捉TimerTask抛出的异样,加上Timer又是单线程的。一旦某个调度工作出现异常,则整个线程就会终止,其余须要调度的工作也不再执行。
- ScheduledThreadPoolExecutor基于线程池来实现调度性能,某个工作抛出异样后,其余工作仍能失常执行。
工作是否具备优先级
- Timer中执行的TimerTask工作整体上没有优先级的概念,只是依照零碎的相对工夫来执行工作。
- ScheduledThreadPoolExecutor中执行的ScheduledFutureTask类实现了java.lang.Comparable接口和java.util.concurrent.Delayed接口,这也就阐明了ScheduledFutureTask类中实现了两个十分重要的办法,一个是java.lang.Comparable接口的compareTo办法,一个是java.util.concurrent.Delayed接口的getDelay办法。在ScheduledFutureTask类中compareTo办法办法实现了工作的比拟,间隔下次执行的工夫距离短的工作会排在后面,也就是说,间隔下次执行的工夫距离短的工作的优先级比拟高。而getDelay办法则可能返回间隔下次工作执行的工夫距离。
是否反对对工作排序
- Timer不反对对工作的排序。
- ScheduledThreadPoolExecutor类中定义了一个动态外部类DelayedWorkQueue,DelayedWorkQueue类实质上是一个有序队列,为须要调度的每个工作依照间隔下次执行工夫距离的大小来排序
是否获取返回的后果
- Timer中执行的TimerTask类只是实现了java.lang.Runnable接口,无奈从TimerTask中获取返回的后果。
- ScheduledThreadPoolExecutor中执行的ScheduledFutureTask类继承了FutureTask类,可能通过Future来获取返回的后果。
通过以上对ScheduledThreadPoolExecutor类和Timer类的剖析比照,置信在JDK 1.5之后,就没有应用Timer来实现定时任务调度的必要了。
二者简略的示例
这里,给出应用Timer和ScheduledThreadPoolExecutor实现定时调度的简略示例,为了简便,我这里就间接应用匿名外部类的模式来提交工作。
Timer类简略示例
源代码示例如下所示。
package io.binghe.concurrent.lab09;
import java.util.Timer;
import java.util.TimerTask;
/**
* @author binghe
* @version 1.0.0
* @description 测试Timer
*/
public class TimerTest {
public static void main(String[] args) throws InterruptedException {
Timer timer = new Timer();
timer.scheduleAtFixedRate(new TimerTask() {
@Override
public void run() {
System.out.println("测试Timer类");
}
}, 1000, 1000);
Thread.sleep(10000);
timer.cancel();
}
}
运行后果如下所示。
测试Timer类
测试Timer类
测试Timer类
测试Timer类
测试Timer类
测试Timer类
测试Timer类
测试Timer类
测试Timer类
测试Timer类
ScheduledThreadPoolExecutor类简略示例
源代码示例如下所示。
package io.binghe.concurrent.lab09;
import java.util.concurrent.*;
/**
* @author binghe
* @version 1.0.0
* @description 测试ScheduledThreadPoolExecutor
*/
public class ScheduledThreadPoolExecutorTest {
public static void main(String[] args) throws InterruptedException {
ScheduledExecutorService scheduledExecutorService = Executors.newScheduledThreadPool(3);
scheduledExecutorService.scheduleAtFixedRate(new Runnable() {
@Override
public void run() {
System.out.println("测试测试ScheduledThreadPoolExecutor");
}
}, 1, 1, TimeUnit.SECONDS);
//主线程休眠10秒
Thread.sleep(10000);
System.out.println("正在敞开线程池...");
// 敞开线程池
scheduledExecutorService.shutdown();
boolean isClosed;
// 期待线程池终止
do {
isClosed = scheduledExecutorService.awaitTermination(1, TimeUnit.DAYS);
System.out.println("正在期待线程池中的工作执行实现");
} while(!isClosed);
System.out.println("所有线程执行完结,线程池敞开");
}
}
运行后果如下所示。
测试测试ScheduledThreadPoolExecutor
测试测试ScheduledThreadPoolExecutor
测试测试ScheduledThreadPoolExecutor
测试测试ScheduledThreadPoolExecutor
测试测试ScheduledThreadPoolExecutor
测试测试ScheduledThreadPoolExecutor
测试测试ScheduledThreadPoolExecutor
测试测试ScheduledThreadPoolExecutor
测试测试ScheduledThreadPoolExecutor
正在敞开线程池...
测试测试ScheduledThreadPoolExecutor
正在期待线程池中的工作执行实现
所有线程执行完结,线程池敞开
留神:对于Timer和ScheduledThreadPoolExecutor还有其余的应用办法,这里,我就简略列出以上两个应用示例,更多的应用办法大家能够自行实现。
发表回复