Java併發——Executor框架ScheduledThreadPoolExecutor詳解

ScheduledThreadPoolExecutor類繼承了ThreadPoolExecutor並實現了ScheduledExecutorService接口。主要用於在給定的延遲後執行任務或者定期執行任務。作用類似於java.util包下的Timer類,但是比Timer功能更強大、更靈活,因爲Timer只能控制單個線程延遲或定期執行,而ScheduledThreadPoolExecutor對應的是多個線程的後臺線程。

一、ScheduledThreadPoolExecutor的創建:

可以利用Executors工廠類來創建兩種ScheduledThreadPoolExecutor: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的工作流程大致如下:

  • 主線程把調用ScheduledFutureTask對象的scheduledAtFixedRate()或者scheduledWithFixedDelay()方法把Runnable或者Callable對象包裝成ScheduledFutureTask對象添加到阻塞隊列中;
  • 線程池中的線程1從阻塞隊列中獲取到期的ScheduledFutureTask任務,並執行任務;(到期的意思就是當前時間大於time)
  • 執行完任務後把成員變量time改爲下次要執行任務的時間,然後把新的ScheduledFutureTask任務重新放入阻塞隊列中;


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章