線程池概述
Java線程池是一種池化技術,用于管理和復用線程,減少線程創建和銷毀的開銷,提高系統性能。Java通過java.util.concurrent
包提供了強大的線程池支持。
線程池參數詳解
1. 核心參數
// 創建線程池的完整構造函數
ThreadPoolExecutor(int corePoolSize, // 核心線程數int maximumPoolSize, // 最大線程數long keepAliveTime, // 空閑線程存活時間TimeUnit unit, // 時間單位BlockingQueue<Runnable> workQueue, // 工作隊列ThreadFactory threadFactory, // 線程工廠RejectedExecutionHandler handler // 拒絕策略處理器
)
2. 參數詳細說明
corePoolSize(核心線程數)
-
線程池中保持的最小線程數量,即使它們是空閑的
-
除非設置了
allowCoreThreadTimeOut
,否則核心線程不會因空閑而被回收
maximumPoolSize(最大線程數)
-
線程池允許創建的最大線程數量
-
當工作隊列滿時,線程池會創建新線程直到達到此限制
keepAliveTime(線程空閑時間)
-
當線程數大于核心線程數時,空閑線程在終止前等待新任務的最長時間
-
僅適用于超出核心線程數的線程
unit(時間單位)
-
keepAliveTime參數的時間單位
-
如TimeUnit.SECONDS、TimeUnit.MILLISECONDS等
workQueue(工作隊列)
-
用于保存等待執行的任務的阻塞隊列
-
常見實現:
-
ArrayBlockingQueue
:有界隊列 -
LinkedBlockingQueue
:無界隊列(默認Integer.MAX_VALUE) -
SynchronousQueue
:不存儲元素的隊列 -
PriorityBlockingQueue
:具有優先級的隊列
-
threadFactory(線程工廠)
-
用于創建新線程的工廠
-
可以自定義線程名稱、優先級等
handler(拒絕策略)
-
當線程池和工作隊列都滿時,處理新提交任務的策略
-
內置策略:
-
AbortPolicy
:默認策略,拋出RejectedExecutionException -
CallerRunsPolicy
:由調用線程執行該任務 -
DiscardPolicy
:直接丟棄任務 -
DiscardOldestPolicy
:丟棄隊列中最舊的任務并嘗試重新提交
-
線程池工作流程
-
提交任務時,如果當前線程數小于corePoolSize,創建新線程執行任務
-
如果線程數達到corePoolSize,新任務被放入工作隊列
-
如果工作隊列已滿且線程數小于maximumPoolSize,創建新線程執行任務
-
如果線程數達到maximumPoolSize且隊列已滿,觸發拒絕策略
代碼示例
import java.util.concurrent.*;
import java.util.concurrent.atomic.AtomicInteger;public class ThreadPoolDemo {// 任務計數器private static AtomicInteger taskCount = new AtomicInteger(1);public static void main(String[] args) {// 創建線程池ThreadPoolExecutor executor = new ThreadPoolExecutor(2, // 核心線程數5, // 最大線程數60, // 空閑線程存活時間TimeUnit.SECONDS, // 時間單位new ArrayBlockingQueue<>(10), // 工作隊列(容量10)new CustomThreadFactory(), // 自定義線程工廠new ThreadPoolExecutor.CallerRunsPolicy() // 拒絕策略);// 提交20個任務for (int i = 0; i < 20; i++) {try {executor.execute(new Task("Task-" + i));} catch (RejectedExecutionException e) {System.out.println("任務被拒絕: " + i);}}// 關閉線程池executor.shutdown();}// 自定義任務static class Task implements Runnable {private String name;public Task(String name) {this.name = name;}@Overridepublic void run() {System.out.println(Thread.currentThread().getName() + " 執行 " + name);try {Thread.sleep(1000); // 模擬任務執行} catch (InterruptedException e) {e.printStackTrace();}System.out.println(Thread.currentThread().getName() + " 完成 " + name);}}// 自定義線程工廠static class CustomThreadFactory implements ThreadFactory {private AtomicInteger threadCount = new AtomicInteger(1);@Overridepublic Thread newThread(Runnable r) {Thread thread = new Thread(r, "CustomThread-" + threadCount.getAndIncrement());thread.setDaemon(false);thread.setPriority(Thread.NORM_PRIORITY);return thread;}}
}
常用預定義線程池
Java通過Executors類提供了幾種常用的線程池:
-
newFixedThreadPool:固定大小線程池
-
newCachedThreadPool:可緩存線程池
-
newSingleThreadExecutor:單線程線程池
-
newScheduledThreadPool:定時任務線程池
// 使用示例
ExecutorService fixedThreadPool = Executors.newFixedThreadPool(5);
ExecutorService cachedThreadPool = Executors.newCachedThreadPool();
注意事項
-
合理設置線程池大小,考慮CPU核心數和任務類型(I/O密集型或CPU密集型)
-
避免使用無界隊列,可能導致內存溢出
-
根據業務需求選擇合適的拒絕策略
-
使用自定義線程工廠便于問題排查和監控
-
正確關閉線程池,調用shutdown()或shutdownNow()
線程池是Java并發編程中的重要組件,合理使用可以顯著提高應用程序的性能和穩定性。