首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> Java 程式設計 >> Java 程式設計入門

Java 線程池核心組件 ThreadPoolExecutor 深度解析

     編輯:Java 程式設計入門

一、線程池執行流程

調用 execute(Runnable command) 提交任務時,處理邏輯如下:

  1. 若當前線程數 < 核心線程數(corePoolSize),創建新線程執行任務。
  2. 若當前線程數 ≥ corePoolSize,任務入隊阻塞隊列(BlockingQueue)。
  3. 若隊列已滿且線程數 < 最大線程數(maximumPoolSize),創建新線程執行任務。
  4. 若隊列滿且線程數達上限,觸發拒絕策略。

二、四種內置拒絕策略

策略類行為
AbortPolicy拋出 RejectedExecutionException(默認)
DiscardPolicy靜默丟棄當前任務
DiscardOldestPolicy丟棄隊列中最舊任務,嘗試重新提交當前任務
CallerRunsPolicy由調用線程(提交任務的線程)直接執行任務

三、核心源碼解析

1. 狀態與線程數打包

ThreadPoolExecutor 使用 AtomicInteger ctl 將「線程池狀態」(高 3 位)與「工作線程數」(低 29 位)打包存儲:

private final AtomicInteger ctl = new AtomicInteger(ctlOf(RUNNING, 0));
private static final int COUNT_BITS = Integer.SIZE - 3; // 29
private static final int CAPACITY   = (1 << COUNT_BITS) - 1;

// 狀態常量(高 3 位)
private static final int RUNNING    = -1 << COUNT_BITS;
private static final int SHUTDOWN   =  0 << COUNT_BITS;
private static final int STOP       =  1 << COUNT_BITS;
private static final int TIDYING    =  2 << COUNT_BITS;
private static final int TERMINATED =  3 << COUNT_BITS;

2. execute() 核心邏輯

public void execute(Runnable command) {
    if (command == null) throw new NullPointerException();
    int c = ctl.get();
    if (workerCountOf(c) < corePoolSize) {
        if (addWorker(command, true)) return;
        c = ctl.get();
    }
    if (isRunning(c) && workQueue.offer(command)) {
        int recheck = ctl.get();
        if (!isRunning(recheck) && remove(command)) reject(command);
        else if (workerCountOf(recheck) == 0) addWorker(null, false);
    } else if (!addWorker(command, false)) {
        reject(command);
    }
}

3. addWorker() 關鍵步驟

  • 雙重檢查線程池狀態與線程數上限。
  • 使用 CAS 增加工作線程計數。
  • 持有 mainLock 將 Worker 加入 HashSet workers。
  • 啟動線程執行任務。

4. Worker 任務執行循環

final void runWorker(Worker w) {
    Thread wt = Thread.currentThread();
    Runnable task = w.firstTask;
    w.firstTask = null;
    w.unlock();
    boolean completedAbruptly = true;
    try {
        while (task != null || (task = getTask()) != null) {
            w.lock();
            try {
                beforeExecute(wt, task);
                task.run();
                afterExecute(task, null);
            } finally {
                task = null;
                w.completedTasks++;
                w.unlock();
            }
        }
        completedAbruptly = false;
    } finally {
        processWorkerExit(w, completedAbruptly);
    }
}

四、常用工廠方法創建的線程池

方法特點適用場景
newFixedThreadPool固定大小,核心=最大,隊列無界長期任務、控制並發度
newSingleThreadExecutor單線程,保證順序執行串行任務
newCachedThreadPool核心 0,最大無界,空閒 60s 回收大量短期異步任務

五、BlockingQueue 核心操作

方法行為
add(e)成功返回 true,失敗拋異常
offer(e)成功 true,失敗 false(不阻塞)
put(e)阻塞直到入隊成功
take()阻塞直到取出元素
poll(timeout)超時返回 null
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved