synchronized 是 Java 內置鎖,用於修飾方法或代碼塊,保證同一時刻只有一個線程執行該段代碼。分為兩種形式:
public synchronized void method(),鎖是當前實例對象(this)。synchronized(obj) { ... },鎖是括號內的對象,常用 this。縮小同步範圍(臨界區),只保護共享數據,提高並發性能。
生活中鎖保護門、箱子;Java 中鎖保護共享數據(堆中實例變量、方法區類變量)。JVM 為每個對象/類關聯一個監視器,監視器通過鎖實現排他訪問。
| 同步形式 | 鎖對象 |
|---|---|
| 實例同步方法 | 當前實例對象(this) |
| 同步代碼塊 | 括號內指定對象 |
| 靜態同步方法 | 當前類的 Class 對象 |
public class ThreadTest implements Runnable {
public synchronized void run() { ... }
public static void main(String[] args) {
for (int i=0; i<5; i++)
new Thread(new ThreadTest()).start(); // 每次 new 新實例,鎖不同,無法同步!
}
}
修正:共享同一實例 new Thread(sharedInstance),或使用 static 同步方法(鎖為 Class 對象)。
四種狀態:無鎖 → 偏向鎖 → 輕量級鎖 → 重量級鎖,隨競爭升級,不可降級。目標:提升獲取/釋放鎖效率。
飢餓成因:高優先級線程佔用 CPU、同步塊無序進入導致線程長期等待、wait() 隨機喚醒。
解決:使用公平鎖(如 ReentrantLock(true)),保證線程按請求順序獲取鎖。
線程可重複獲得自己持有的鎖,計數器機制:獲取 +1,釋放 -1,歸零才真正釋放。避免父子類同步方法調用死鎖。
提供比 synchronized 更靈活的鎖機制:
Object.wait/notify。synchronized 經過 JDK 1.6 優化(偏向鎖、輕量級鎖、自旋、消除、粗化),性能大幅提升,代碼簡潔,首選。Lock 提供更豐富語義(公平、可中斷、條件變量),適用於複雜並發控制場景。理解鎖升級、可重入、公平性原理,是編寫高性能並發程序的基石。