現代作業系統支援多任務,進程是獨立的內存空間(如一個 .exe),線程是進程內的執行流程,共享進程內存。Java 中線程對應 java.lang.Thread 實例,每個線程擁有獨立調用棧。主線程從 main() 開始,新線程創建即產生新棧。線程分用戶線程(JVM 等待其結束)和守護線程(如 GC,不阻止 JVM 退出)。
run(),調用 start() 啟動(切勿直接調用 run())new Thread(runnable) 包裝關鍵點:
start()啟動新線程並進入可運行狀態;run()只是普通方法調用,不會創建新線程。線程一旦啟動不可重複啟動,run() 結束即死亡。
五大狀態:新建 → 可運行 → 運行 → 等待/阻塞/睡眠 → 死亡。調度器從可運行池選線程執行,時間片用完或阻塞則回可運行池。阻塞三種形式:sleep() 釋放 CPU 但保持鎖;wait() 釋放鎖並進入等待池;同步鎖阻塞進入鎖池。
Thread.sleep(ms):靜態方法,當前線程休眠指定時間,到期回可運行狀態(不保證立即執行)Thread.yield():當前線程讓步回可運行狀態,嘗試讓同優先級線程執行(無保證)t.join():當前線程等待 t 結束,可設超時;本質是調用 wait()必須在 同步塊/方法內調用,調用者需持有對象鎖。wait() 釋放鎖進入等待集;notify() 隨機喚醒一個;notifyAll() 喚醒全部。經典生產者-消費者模式需配合條件判斷(while 循環檢查),防止虛假喚醒。
synchronized 方法/塊自動獲取/釋放this,靜態同步鎖 Class 對象即使類是線程安全的(如 Vector),複合操作(先檢查後操作)仍需額外同步。例如「檢查非空再刪除」兩步操作間隙可能被其他線程修改數據。
多線程循環等待對方持有的鎖。避免策略:固定獲取鎖順序、使用 tryLock 超時、減少鎖嵌套。
| 組件 | 核心特點 |
|---|---|
| Lock/ReadWriteLock | 顯式鎖,支援公平/非公平、可中斷、超時獲取、多條件變量 |
| ConcurrentHashMap | 分段鎖(Segment)+ volatile value,讀無鎖,寫鎖段,高並發下優於 Hashtable |
| CopyOnWriteArrayList | 寫時復制,讀無鎖,適合讀多寫少,最終一致性 |
| BlockingQueue | 阻塞隊列:ArrayBlockingQueue(有界)、LinkedBlockingQueue(無界)、SynchronousQueue(直接傳遞) |
| ThreadPoolExecutor | 核心/最大線程數、存活時間、工作隊列、拒絕策略,避免頻繁創建銷毀開銷 |
| Semaphore | 計數信號量,控制資源訪問許可數 |
| CountDownLatch/CyclicBarrier | 障礙器:前者倒計時等待,後者循環攔截,適合多任務分階段同步 |
| Atomic 系列 | CAS 無鎖原子操作,單變量線程安全 |
| Callable/Future | 可返回結果、拋異常的任務,配合線程池實現異步計算 |
Executors 工廠方法快速創建:newFixedThreadPool、newSingleThreadExecutor、newCachedThreadPool、newScheduledThreadPool。自定義池需理解 7 參數構造器:核心數、最大數、存活時間、時間單位、工作隊列、線程工廠、拒絕策略。
優先級 1-10(默認 5),高優先級獲取 CPU 概率大但非絕對。切勿依賴優先級實現業務邏輯,調度器行為跨平台差異大。守護線程(setDaemon(true))需在 start() 前設置,JVM 僅剩守護線程時退出。
Java 多線程從基礎 Thread/Runnable 到 JUC 並發包,核心始終圍繞共享數據安全訪問與線程協作調度。掌握 synchronized、volatile、Lock、CAS、各類隊列與同步工具的適用場景,才能編寫高效、正確的並發程序。實戰中優先使用高層並發工具(Executor、Concurrent 集合、同步器),減少手動同步複雜度。