⑴ Java線程池newFixedThreadPool源碼分析
本文深入探討了Java線程池的創建與任務提交機制,以`newFixedThreadPool`為例進行源碼分析。首先,`Executors.newFixedThreadPool()`創建線程池時,底層調用`ThreadPoolExecutor`的構造函數,核心與最大線程數默認值傳入,線程存活時間默認為0毫秒。值得注意的是,`workQueue`底層採用`LinkedBlockingQueue`,容量設置為`Integer.MAX_VALUE`,意味著任務隊列容量無限大,極端情況下可能導致內存溢出。
在自定義線程池時,用戶需明確傳入隊列`workQueue`,並賦予其實際容量。`workQueue`內部實現為鏈表結構,初始化時設置`last`和`head`為`null`,在`execute`方法中再次涉及隊列操作。進一步分析,`ThreadPoolExecutor`調用自身內部構造函數,核心參數保持一致,隊列設置為`new LinkedBlockingQueue()`,工廠為默認線程工廠,過期策略默認為`AbortPolicy()`。
`ThreadPoolExecutor`繼承自`AbstractExecutorService`,後者實現了`Executors`介面,提供了創建線程池的基礎框架。創建線程池時,系統會進行一系列參數合法性檢查,確保傳入的參數合理,包括核心與最大線程數、存活時間等,同時驗證隊列、工廠、過期策略是否非空。
接著,我們將視線轉移到`submit`方法,通過`submit()`向線程池提交任務。此操作實際由`AbstractExecutorService`實現,支持`Runnable`與`Callable`的提交,二者皆轉為`RunnableFuture`。`newTaskFor`方法中,`FutureTask`類被構造,實現了`RunnableFuture`介面,繼承了`Runnable`與`Future`。因此,`submit`方法最終生成`FutureTask`對象,通過`run`方法執行,實際由內部`callable`屬性實現。
`execute(FutureTask)`方法由`ThreadPoolExecutor`實現,接收`FutureTask`作為參數。方法首先檢查`FutureTask`是否為`null`,並進行相關注釋。接著,進行一系列判斷,包括線程池狀態、隊列容量與新任務狀態等,確保線程池狀態合法、任務與隊列匹配。
在`addWorker`方法中,`ctl`變數被用於記錄線程池的生命周期狀態與當前工作線程數。`ctl`通過`ctlOf`方法封裝`runState`與`workerCount`,並提供解封裝方法,如`runStateOf`、`workerCountOf`等。`COUNT_BITS`與`CAPACITY`常量用於處理`ctl`變數的位操作,以實現高效狀態管理。
`execute`方法執行邏輯分為兩部分:一部分處理核心線程數與工作線程數的關系,通過`addWorker`方法動態擴展線程池;另一部分處理隊列任務的提交與執行,確保線程池狀態與任務需求相匹配。`addWorker`方法內部,通過CAS操作安全增加工作線程數,並根據線程池狀態與新任務狀態執行相應邏輯。`Worker`類作為線程執行器,繼承`AbstractQueuedSynchronizer`,實現`Runnable`介面,封裝任務執行邏輯。
`runWorker`方法實現線程執行邏輯,包括從隊列獲取任務、處理線程池狀態與異常情況、執行任務與任務完成後的工作清理。`FutureTask`的`run`方法調用任務執行邏輯,並將結果存儲在`outcome`中,供後續獲取返回值。
`execute`方法第三部分處理線程池滿載或核心線程數量時的擴展邏輯,通過隊列`offer`方法添加任務,並根據線程池狀態與隊列容量調整工作線程數。`LinkedBlockingQueue`中的`offer`方法實現隊列元素的添加,利用`AtomicInteger`類的`getAndIncrement`方法安全更新隊列元素計數。`Condition`機制用於線程間的同步與喚醒,確保線程池與任務隊列的高效管理。
總之,`newFixedThreadPool`源碼展示了Java線程池管理的高效與靈活性。通過深入理解線程池的創建、任務提交與執行機制,開發者能夠更好地利用線程池優化應用性能,解決並發編程中的資源管理與任務調度問題。本文僅提供了一個簡要概述,實際源碼細節與更多優化策略值得進一步探索與研究。