基礎概念篇
1. 線程 vs 進程
- 進程:資源分配單位,獨立內存空間
- 線程:CPU 調度單位,共享進程內存(堆/方法區),私有棧/PC 寄存器
2. 創建線程三種方式
- 繼承
Thread 重寫 run()
- 實現
Runnable 接口(推薦,支持多實現、線程池)
- 實現
Callable + FutureTask(有返回值、可拋異常)
3. start() vs run()
start():啟動新線程,JVM 調用 run()
run():普通方法調用,主線程同步執行,無新線程
4. Runnable vs Callable
| 特性 | Runnable | Callable |
| 返回值 | 無 | 泛型 V |
| 異常 | 不可拋出 | 可拋出 |
| 方法 | run() | call() |
| 配合 | Thread/Executor | FutureTask/ExecutorService |
同步與鎖篇
5. synchronized vs ReentrantLock
synchronized:關鍵字,JVM 內置,自動釋放,不可中斷,無超時,公平性不可控
ReentrantLock:API 級,手動 lock()/unlock(),支持公平/非公平、可中斷、超時獲取、Condition 多條件變量
6. volatile 關鍵字
- 保證可見性:寫入後對其他線程立即可見
- 禁止指令重排:內存屏障
- 不保證原子性:
count++ 仍非線程安全
7. AQS 核心原理
- 狀態
state + FIFO 雙向隊列 + CAS 自旋
- 獨占模式:
tryAcquire/tryRelease(ReentrantLock)
- 共享模式:
tryAcquireShared/tryReleaseShared(CountDownLatch、Semaphore)
8. 死鎖四條件與避免
- 互斥條件
- 請求保持
- 不可剝奪
- 循環等待 → 破壞此條件:統一鎖獲取順序(按 hashCode 排序)
並發工具類篇
9. CountDownLatch vs CyclicBarrier
| 特性 | CountDownLatch | CyclicBarrier |
| 可重用 | 否 | 是 |
| 核心場景 | 主線程等待多子線程完成 | 多線程相互等待齊聚 |
| 攔截動作 | 無 | 支持 barrierAction |
10. ThreadLocal 原理與內存洩漏
- 每個 Thread 內部
ThreadLocalMap<ThreadLocal>, Object>
- Key 為弱引用,Value 強引用 → Thread 不銷毀時 Value 洩漏
- 必須調用
remove() 清理
11. 線程池七大參數
new ThreadPoolExecutor(
corePoolSize, maximumPoolSize, keepAliveTime, TimeUnit,
workQueue, threadFactory, handler // 拒絕策略
)
- 拒絕策略:AbortPolicy(默認拋異常)、CallerRunsPolicy(調用者執行)、DiscardPolicy(丟棄)、DiscardOldestPolicy(丟棄最老)
12. submit() vs execute()
execute(Runnable):void,Executor 接口
submit(Callable/Runnable):返回 Future,ExecutorService 接口
進階原理篇
13. Java 內存模型 (JMM) Happens-Before 規則
- 程序次序規則
- 管程鎖定規則
- volatile 變量規則
- 線程啟動規則
- 線程終止規則
- 對象終結規則
- 傳遞性
14. CAS 與 ABA 問題
- CAS:Compare-And-Swap,樂觀鎖,硬件指令
- ABA:值 A→B→A,CAS 誤以為未變
- 解決:
AtomicStampedReference(版本戳)、AtomicMarkableReference(標記位)
15. Fork/Join 工作竊取
- 雙端隊列:頭部取任務執行,尾部竊取任務
- 適用:遞歸分治、計算密集型
最佳實踐 5 條
- 命名有意義:
OrderProcessor-1 而非 Thread-1,利於排查
- 縮小同步範圍:優先同步塊而非同步方法,減少臨界區
- 優先並發工具類:CountDownLatch、Semaphore、CompletableFuture 替代 wait/notify
- 優先並發集合:ConcurrentHashMap、CopyOnWriteArrayList 替代 Collections.synchronizedXxx
- 不可變對象:final、無 setter、防御性拷貝,從根源消除線程安全問題
常見陷阱提示
Thread.stop() 已棄用(破壞鎖一致性)
HashMap 多線程 put 導致死循環(JDK 7)/ 數據丟失(JDK 8)
SimpleDateFormat 非線程安全,用 ThreadLocal 或 DateTimeFormatter
- 雙重檢查鎖單例需
volatile 修飾 instance
parallelStream() 共用 ForkJoinPool.commonPool,CPU 密集型任務會相互影響