JAVA线程池:ScheduledThreadPoolExecutor
Posted Vashon_杨博程
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了JAVA线程池:ScheduledThreadPoolExecutor相关的知识,希望对你有一定的参考价值。
前言
自JDK1.5开始,JDK提供了ScheduledThreadPoolExecutor类来支持周期性任务的调度。在这之前的实现需要依靠Timer和TimerTask或者其它第三方工具来完成,但Timer有不少的缺陷:
- Timer是单线程模式;
- 如果在执行任务期间某个TimerTask耗时较久,那么就会影响其它任务的调度;
- Timer的任务调度是基于绝对时间的,对系统时间敏感;
- Timer不会捕获执行TimerTask时所抛出的异常,由于Timer是单线程,所以一旦出现异常,则线程就会终止,其他任务也得不到执行。
ScheduledThreadPoolExecutor继承ThreadPoolExecutor来重用线程池的功能,它的实现方式如下:
- 将任务封装成ScheduledFutureTask对象,ScheduledFutureTask基于相对时间,不受系统时间的改变所影响;
- ScheduledFutureTask实现了
java.lang.Comparable
接口和java.util.concurrent.Delayed
接口,所以有两个重要的方法:compareTo和getDelay。compareTo方法用于比较任务之间的优先级关系,如果距离下次执行的时间间隔较短,则优先级高;getDelay方法用于返回距离下次任务执行时间的时间间隔; - ScheduledThreadPoolExecutor定义了一个DelayedWorkQueue,它是一个有序队列,会通过每个任务按照距离下次执行时间间隔的大小来排序;
- ScheduledFutureTask继承自FutureTask,可以通过返回Future对象来获取执行的结果。
通过如上的介绍,可以对比一下Timer和ScheduledThreadPoolExecutor:
Timer | ScheduledThreadPoolExecutor |
---|---|
单线程 | 多线程 |
单个任务执行时间影响其他任务调度 | 多线程,不会影响 |
基于绝对时间 | 基于相对时间 |
一旦执行任务出现异常不会捕获,其他任务得不到执行 | 多线程,单个任务的执行不会影响其他线程 |
Timer和TimerTask的使用
这个大家应该都是会使用的了,示例代码如下:
Timer timer = new Timer();
timer.schedule(new TimerTask() {
@Override
public void run() {
log.e("time:");
}
}, 2000, 40);//2000表示第一次执行任务延迟时间,40表示以后每隔多长时间执行一次run里面的任务
ScheduledThreadPoolExecutor的使用
SchedualedThreadPoolExecutor 接收SchduledFutureTask类型的任务,是线程池调度任务的最小单位,有三种提交任务的方式:
- schedule:延迟多长时间之后只执行一次;
- scheduledAtFixedRate:延迟指定时间后执行一次,之后按照固定的时长周期执行;
- scheduledWithFixedDelay:延迟指定时间后执行一次,之后按照:上一次任务执行时长 + 周期的时长 的时间去周期执行;
/**
* 定时任务线程池
*/
public class ScheduledThreadPoolExecutorTest {
public static void main(String args[]) {
ScheduledExecutorService scheduledThreadPool = Executors.newScheduledThreadPool(5);
int time = 2000; // 延迟2秒执行
MyTask task = new MyTask("定时任务线程");
// 1、schedule:延迟多长时间之后只执行一次(延迟2秒执行)
scheduledThreadPool.schedule(task, time, TimeUnit.MILLISECONDS);
// 2、scheduledAtFixedRate:延迟指定时间后执行一次,之后按照固定的时长周期执行(延迟2秒执行,之后间隔3秒执行)
//scheduledThreadPool.scheduleAtFixedRate(task,time,3000,TimeUnit.MILLISECONDS);
// 3、scheduledWithFixedDelay:延迟指定时间后执行一次,之后按照:上一次任务执行时长 + 周期的时长 的时间去周期执行(延迟2秒执行,之后间隔上次任务执行时长+周期时长执行)
scheduledThreadPool.scheduleWithFixedDelay(task,time,3000,TimeUnit.MILLISECONDS);
//mScheduledThreadPoolExecutor.shutdown();
}
}
class MyTask implements Runnable {
private String TAG = "";
public MyTask(String tag) {
TAG = tag;
}
@Override
public void run() {
System.out.println(TAG + "\\t" + System.currentTimeMillis());
}
}
以上是关于JAVA线程池:ScheduledThreadPoolExecutor的主要内容,如果未能解决你的问题,请参考以下文章