JDK自帶的排程有遠古時代的Timer 和Task
JUC包的ScheduledExecutorService 本節重點研究ScheduledExecutorService;
代碼示例如下:
public static void main(String[] args) {
ScheduledExecutorService scheduledExecutorService = Executors.newScheduledThreadPool(3);
Runnable runnable = new Runnable() {
@Override
public void run() {
try {
System.out.println("開始排程了");
} catch (Throwable ignored) {
}
}
};
scheduledExecutorService.scheduleAtFixedRate(runnable, 0, 1, TimeUnit.MINUTES);
}
關于線程池相關的 重點參數有 :
corePoolSize :核心線程數 maximumPoolSize:最大線程數
keepAliveTime 當線程池數量超過 核心線程數之後,決定線程等待新任務的最大等待時間
TimeUnit:最大等待時間的機關
BlockingQueue<Runnable> workQueue:此用延遲隊列
ThreadFactory threadFactory:線程工廠類 一般定義一下線程的名字 等
RejectedExecutionHandler handler:拒絕政策 常見的有以下幾種:
ThreadPoolExecutor.AbortPolicy:丢棄任務并抛出RejectedExecutionException異常。
ThreadPoolExecutor.DiscardPolicy:也是丢棄任務,但是不抛出異常。
ThreadPoolExecutor.DiscardOldestPolicy:丢棄隊列最前面的任務,然後重新嘗試執行任務(重複此過程)
ThreadPoolExecutor.CallerRunsPolicy:由調用線程處理該任務
開始主核心邏輯解析:
scheduledExecutorService.scheduleAtFixedRate(runnable, 0, 1, TimeUnit.MINUTES);
代碼不多直接貼上:
public ScheduledFuture<?> scheduleAtFixedRate(Runnable command,
long initialDelay,
long period,
TimeUnit unit) {
//1.參數檢查
if (command == null || unit == null)
throw new NullPointerException();
if (period <= 0)
throw new IllegalArgumentException();
//2.根據延遲時間,和執行周期建立 ScheduledFutureTask 對象
ScheduledFutureTask<Void> sft =
new ScheduledFutureTask<Void>(command,
null,
triggerTime(initialDelay, unit),
unit.toNanos(period));
//3.裝飾
RunnableScheduledFuture<Void> t = decorateTask(command, sft);
sft.outerTask = t;
delayedExecute(t);
return t;
}
類的結構:

ScheduledFutureTask繼承了 FutureTask 實作了 RunnableScheduledFuture
private void delayedExecute(RunnableScheduledFuture<?> task) {
if (isShutdown())
reject(task);
else {
//1.任務加入延遲隊列
super.getQueue().add(task);
if (isShutdown() &&
!canRunInCurrentRunState(task.isPeriodic()) &&
remove(task))
task.cancel(false);
else
//啟動任務執行
ensurePrestart();
}
}