在「單物件多執行緒」場景下,同步問題主要源自兩個維度:
每個執行緒持有獨立的 Runnable 實例,自然隔離實例變數。
缺點:無法真正共享狀態,適用於無狀態任務。
將共享變數移入 run() 方法內部,每次呼叫各自擁有獨立副本。
優點:無鎖、效能最高、線程安全。
適用:變數生命週期僅限於單次任務執行。
ThreadLocal 為每個執行緒提供獨立的變數副本,雖在程式碼層面看似共享,實則隔離。
適用:需跨方法傳遞執行緒上下文(如資料庫連線、Session、事務 ID)。
透過 synchronized(this) 或 synchronized(lockObj) 將關鍵區段序列化。
// 執行緒 1 持有 lockA 等待 lockB
// 執行緒 2 持有 lockB 等待 lockA
synchronized(lockA) {
synchronized(lockB) { ... }
}
解決:統一鎖獲取順序、使用 tryLock(timeout)、避免嵌套鎖。
文章示範如何基於 wait()/notify() 機制,構建支援 啟動、休眠、喚醒、停止 四種狀態的執行緒池,並透過 Socket 指令遠端控制。核心類別:
MyThread:攜帶狀態機的工作執行緒MyThreadManager:統一管理執行緒生命週期MyThreadPool:Socket 伺服器端,解析指令分派任務此為教學示範,生產環境請直接使用 JDK 內建工具包。
| 類型 | 特性 | 適用場景 |
|---|---|---|
| FixedThreadPool | 固定核心數,隊列無界 | 長期穩定負載,控制併發上限 |
| CachedThreadPool | 核心數 0,最大 Integer.MAX_VALUE,60s 回收閒置 | 大量短生命週期任務 |
| ScheduledThreadPool | 支援定時/週期性執行 | 定時任務、延遲執行、週期輪詢 |
| 特性 | CyclicBarrier | CountDownLatch |
|---|---|---|
| 機制 | 所有執行緒到達屏障點才能繼續,可重複使用 | 倒數計數歸零釋放等待者,一次性 |
| 典型場景 | 多執行緒分階段計算、迭代同步 | 主執行緒等待多個初始化任務完成 |
| 核心方法 | await() | countDown() / await() |
java.util.concurrent 高階工具,減少手寫同步錯誤ConcurrentHashMap、LongAdder 等)