1.線程池基礎概念
線程池是一種資源復用技術,通過預先創建并管理一組線程,減少頻繁創建和銷毀線程的開銷。核心思想與數據庫連接池、字符串常量池類似,旨在提升系統性能。
核心參數解析
ThreadPoolExecutor
構造函數包含7個關鍵參數:corePoolSize
:核心線程數,長期保持活躍的線程數量。maximumPoolSize
:線程池最大容量,包括核心線程和非核心線程。keepAliveTime
:非核心線程空閑存活時間。unit
:存活時間單位(如秒、毫秒)。workQueue
:任務隊列,用于存放待執行任務(如ArrayBlockingQueue
、LinkedBlockingQueue
)。threadFactory
:自定義線程創建邏輯。handler
:拒絕策略(如AbortPolicy
拋出異常、CallerRunsPolicy
由提交線程執行任務)。
線程池工作流程
- 任務提交后,優先使用核心線程處理。
- 核心線程全忙時,任務進入工作隊列。
- 隊列滿后,啟用非核心線程(不超過
maximumPoolSize
)。 - 線程和隊列均滿時,觸發拒絕策略。
拒絕策略類型
AbortPolicy
:直接拋出RejectedExecutionException
。CallerRunsPolicy
:提交任務的線程自行執行任務。DiscardOldestPolicy
:丟棄隊列中最老的任務。DiscardPolicy
:靜默丟棄新提交的任務。
任務提交方法
execute(Runnable task)
:無返回值,適用于異步任務。submit(Callable<T> task)
:返回Future<T>
,可獲取執行結果。
線程池關閉
shutdown()
:平滑關閉,等待所有任務完成。shutdownNow()
:立即中斷所有線程,返回未執行任務列表。2.線程池的工作流程
3.ThreadLocal原理與應用
ThreadLocal為每個線程提供獨立的變量副本,解決多線程共享變量的線程安全問題。
基本使用
static ThreadLocal<Integer> threadLocal = ThreadLocal.withInitial(() -> 1);public static void main(String[] args) {new Thread(() -> {threadLocal.set(10);threadLocal.set(threadLocal.get() + 5);System.out.println(Thread.currentThread().getName() + ":" + threadLocal.get());threadLocal.remove(); // 防止內存泄漏}).start();new Thread(() -> {threadLocal.set(20);threadLocal.set(threadLocal.get() + 10);System.out.println(Thread.currentThread().getName() + ":" + threadLocal.get());threadLocal.remove();}).start();
}
內存泄漏問題
ThreadLocal的鍵(ThreadLocal對象)被弱引用管理,值(變量副本)為強引用。若ThreadLocal實例被回收,但線程未終止,Entry中的值會持續占用內存。
解決方案:
- 顯式調用
remove()
清理Entry。 - 避免長生命周期線程(如線程池線程)使用ThreadLocal時未清理。
引用類型對比
- 強引用:對象被直接引用,不會被GC回收(
Object obj = new Object()
)。 - 軟引用(
SoftReference
):內存不足時回收,適合緩存場景。 - 弱引用(
WeakReference
):GC時立即回收,常用于ThreadLocal鍵。
線程創建方式總結
- 繼承Thread類:重寫
run()
方法。 - 實現Runnable接口:更靈活,推薦使用。
- 實現Callable接口:可返回結果,配合
FutureTask
使用。 - 線程池:高效管理線程資源,實際開發首選。
通過合理使用線程池和ThreadLocal,可顯著提升多線程程序的性能和安全性。