核心概念辨析
| 概念 | 定義 | 關鍵點 |
| 併發 | 同一時間段內多任務交替執行 (單核 CPU) | 微觀交替、宏觀同時 |
| 並行 | 同一時刻多任務同時執行 (多核 CPU) | 物理同時 |
| 進程 | 資源分配基本單位,獨立地址空間 (代碼/數據/棧) | 重量級、隔離性強 |
| 線程 | CPU 調度基本單位,共享進程資源,獨立棧/PC 計數器 | 輕量級、切換開銷小 |
多線程創建三種方式
- 繼承
Thread 重寫 run()
- 實作
Runnable 傳入 Thread (推薦,解耦任務與執行)
- 實作
Callable + FutureTask (可回傳結果、拋異常)
線程生命週期 (6 狀態)
NEW → RUNNABLE → RUNNING → BLOCKED/WAITING/TIMED_WAITING → TERMINATED
核心同步機制對比
| 機制 | 關鍵字/類 | 特點 | 適用場景 |
| 同步鎖 | synchronized | 可重入、公平性差、JVM 優化多 (偏向鎖/輕量級鎖/膨脹) | 一般臨界區 |
| 顯式鎖 | ReentrantLock | 可中斷 lockInterruptibly、超時 tryLock、公平/非公平可選 | 需中斷/超時控制 |
| 讀寫鎖 | ReentrantReadWriteLock | 讀讀共享、讀寫/寫寫互斥 | 讀多寫少 |
| volatile | volatile | 可見性+有序性、無原子性 | 狀態標記、DCL |
| 原子類 | AtomicInteger 等 | CAS 無鎖、高併發計數器 | 計數、單變量更新 |
線程協作機制
wait/notify/notifyAll:Object 監視器方法,**必須在 synchronized 內調用**
CountDownLatch:倒數閂,等待 N 個任務完成
CyclicBarrier:循環柵欄,N 執行緒互相等待
Semaphore:信號量,控制並發存取數量 (許可證)
Exchanger:雙方交換數據
線程池:Executor 框架
// 推薦使用工廠方法
ExecutorService fixed = Executors.newFixedThreadPool(10);
ExecutorService cached = Executors.newCachedThreadPool();
ExecutorService single = Executors.newSingleThreadExecutor();
ExecutorService scheduled = Executors.newScheduledThreadPool(5);
// 手動配置 ThreadPoolExecutor (生產環境推薦)
new ThreadPoolExecutor(
corePoolSize, maximumPoolSize, keepAliveTime, TimeUnit.SECONDS,
new LinkedBlockingQueue<>(),
new ThreadFactoryBuilder().setNameFormat("worker-%d").build(),
new ThreadPoolExecutor.AbortPolicy() // 拒絕策略
);
核心參數:核心/最大線程數、存活時間、工作隊列、線程工廠、拒絕策略 (Abort/Discard/CallerRuns)。
併發容器
| 容器 | 特點 | 適用場景 |
ConcurrentHashMap | JDK8: CAS + synchronized + 紅黑樹,分段鎖 → Node 鎖 | 高併發 Map |
CopyOnWriteArrayList/Set | 寫時複製,讀無鎖,迭代器快照 | 讀多寫少、遍歷頻繁 |
BlockingQueue | ArrayBlockingQueue/LinkedBlockingQueue/SynchronousQueue | 生產者消費者 |
ConcurrentLinkedQueue | 無界、非阻塞、CAS | 高併發隊列 |
面試高頻 25 題精選 (附答案要點)
- 進程 vs 線程:資源分配 vs 調度單位,地址空間隔離 vs 共享
- 多線程優勢:CPU 利用率、資源共享、響應性
- 用戶線程 vs 守護線程:JVM 退出條件、
setDaemon(true) 需在 start() 前
- 創建線程方式:Runnable > Thread > Callable
- 生命週期:6 狀態轉換圖
- 直接呼叫 run():同步執行,非新線程
- sleep vs wait:sleep 不釋放鎖、wait 釋放鎖並進入等待集
- 線程優先級:1-10,僅提示調度器,OS 相關
- 線程調度器/時間片:OS 層面,Java 不可控
- 上下文切換:保存/恢復 CPU 狀態 (PC/暫存器/棧指針)
- 確保 main 最後結束:
join() 或 CountDownLatch
- 線程通信:
wait/notify、BlockingQueue、volatile、CountDownLatch
- wait/notify 定義在 Object:每個物件天然有監視器鎖
- wait/notify 必須在 synchronized:需持有鎖才能進入等待集/喚醒
- sleep/yield 為 static:作用於當前執行緒,無意義傳入其他線程
- 線程安全手段:同步、原子類、鎖、volatile、不可變類、線程封閉
- volatile 作用:可見性、有序性、非原子性
- 同步方法 vs 同步塊:塊粒度更細、效能更好
- ThreadLocal:線程私有變量,
ThreadLocalMap 儲存於 Thread 內
- ThreadGroup:已過時,勿用
- Thread Dump 獲取:
jstack pid、kill -3、JVisualVM
- 死鎖分析/避免:Dump 找 BLOCKED、避免嵌套鎖、有序加鎖、tryLock 超時
- Timer vs ScheduledExecutorService:後者支援線程池、異常處理更好
- 線程池核心參數:7 大參數含義與拒絕策略
- 原子操作/CAS:
compareAndSwap 硬體指令、ABA 問題、AtomicStampedReference
實戰經驗總結
- 優先使用
ExecutorService 管理線程,避免手動 new Thread
- 鎖粒度越細越好,但避免過度優化
- 併發容器優於手動同步集合
- 不可變物件是線程安全的銀彈
- 生產環境必配
-XX:+HeapDumpOnOutOfMemoryError 與線程 Dump 定時腳本