ScheduledThreadPoolExecutor 详解

目录

一、ScheduledThreadPoolExecutor的创建

二、ScheduledThreadPoolExecutor的实现


ScheduledThreadPoolExecutor 类继承了  ThreadPoolExecutor并实现了 ScheduledExecutorService接口。主要用于在给定的延迟后执行任务或者定期执行任务。作用类似于java.util包下的 Timer类,但是比 Timer功能更强大、更灵活,因为 Timer只能控制单个线程延迟或定期执行,而 ScheduledThreadPoolExecutor对应的是多个线程的后台线程。

一、ScheduledThreadPoolExecutor的创建


可以利用 Executors工厂类创建定期执行任务:ScheduledThreadPoolExecutor SingleThreadScheduledExecutor

ScheduledThreadPoolExecutor:适用于若干个(固定)线程延时或者定期执行任务,同时为了满足资源管理的需求而需要限制后台线程数量的场景。

ScheduledExecutorService stp = Executors.newScheduledThreadPool(int threadNums);
ScheduledExecutorService stp = Executors.newScheduledThreadPool(int threadNums, ThreadFactory threadFactory);

SingleThreadScheduledExecutor:适用于需要单个线程延时或者定期的执行任务,同时需要保证各个任务顺序执行的应用场景。

ScheduledExecutorService stse = Executors.newSingleThreadScheduledExecutor(int threadNums);
ScheduledExecutorService stp = Executors.newSingleThreadScheduledExecutor(int threadNums, ThreadFactory threadFactory);

二、ScheduledThreadPoolExecutor的实现


通过查看源码,可以发现 ScheduledThreadPoolExecutor的实现主要是通过把任务封装为 ScheduledFutureTask来实现。ScheduledThreadPoolExecutor通过它的 scheduledAtFixedTime() 方法或者scheduledWithFixedDelay()方法向阻塞队列添加一个实现了 RunnableScheduledFutureTask接口的 ScheduledFutureTask类对象。

ScheduledFutureTask 主要包括3个成员变量:

private final long sequenceNumber;
private long time;
private final long period;

sequenceNumber序列号,用于保存任务添加到阻塞队列的顺序;
time用于保存该任务将要被执行的具体时间;
period周期,用于保存任务执行的间隔周期;

此外,ScheduledTreadPoolExecutor的阻塞队列是用 DelayQueue实现的,可以实现元素延时 delayTime后才能获取元素,在 ScheduledThreadPoolExecutor中,DelayQueue内部封装了一个 PriorityQueue,来对任务进行排序,首先对 time排序,time小的在前,如果 time一样,则 sequence小的在前,也就是说如果 time一样,那么先被提交的任务先执行。因为 DelayQueue是一个无界的队列,因此线程池的 maximumPoolSize是无效的。ScheduledThreadPoolExecutor的工作流程大致如下:


【1】主线程把调用 ScheduledFutureTask对象的 scheduledAtFixedRate() 或者scheduledWithFixedDelay()方法,把 Runnable或者 Callable对象包装成 ScheduledFutureTask对象添加到阻塞队列中;
【2】线程池中的线程1从阻塞队列中获取到期的 ScheduledFutureTask任务,并执行任务;(到期的意思就是当前时间大于time)
【3】执行完任务后把成员变量 time改为下次要执行任务的时间,然后把新的 ScheduledFutureTask任务重新放入阻塞队列中;

猜你喜欢

转载自blog.csdn.net/zhengzhaoyang122/article/details/109347696
今日推荐