首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> Java 程式設計 >> Java 綜合教學

Java 線程同步機制:synchronized、鎖狀態與最佳實踐

     編輯:Java 綜合教學

為什麼需要同步

多線程並發訪問共享可變數據時,會出現原子性違反(如 i++ 非原子)、可見性問題(缓存未刷新)、有序性問題(指令重排)。同步機制保證臨界區同一時刻僅一線程執行。

synchronized 兩種用法

1. 同步方法

public synchronized void deposit(int amount) {
    balance += amount;  // 隱式鎖:this
}

public static synchronized void staticMethod() {
    // 隱式鎖:ClassName.class
}

2. 同步代碼塊(推薦,粒度更細)

public void withdraw(int amount) {
    synchronized (this) {  // 或私有鎖對象
        if (balance >= amount) balance -= amount;
    }
}

// 私有鎖對象模式(封裝性更好)
private final Object lock = new Object();
public void transfer(Account target, int amt) {
    synchronized (lock) {
        synchronized (target.lock) {  // 注意:固定獲取順序防死鎖
            this.withdraw(amt);
            target.deposit(amt);
        }
    }
}

鎖的獲取與釋放規則

場景鎖行為
進入 synchronized 區塊嘗試獲取鎖,失敗則進入阻塞隊列
正常退出區塊釋放鎖,喚醒阻塞隊列一線程
拋出異常退出自動釋放鎖
調用 wait()釋放鎖,進入等待集
調用 sleep()/yield()不釋放鎖

鎖升級與對象頭佈局 (HotSpot)

Object Header (64-bit):
| Mark Word (64 bits)          | Klass Pointer |
| hash(25) | age(4) | bias(1) | lock(2) | epoch(32) | ... |

鎖狀態流向:
無鎖 → 偏向鎖 → 輕量級鎖 → 重量級鎖
      (CAS)      (CAS自旋)    (OS互斥量)
  • 偏向鎖:單線程重複獲取,無 CAS 開銷
  • 輕量級鎖:多線程交替,CAS 自旋
  • 重量級鎖:高競爭,線程阻塞

常見陷阱與避坑

錯誤代碼問題修正
synchronized(new Object())每次新對象,無同步效果用共享 final 鎖對象
synchronized(String.class) 配合 synchronized(this)鎖對象不同,互不阻塞統一鎖對象
鎖住長耗時操作 (IO、sleep)吞吐率極低縮小臨界區,異步化
雙重檢查鎖單例 (無 volatile)指令重排導致半初始化對象加 volatile 或用內部類

現代替代方案 (java.util.concurrent)

  • ReentrantLock:可中斷、可超時、公平鎖、多條件 Condition
  • ReadWriteLock:讀讀並行、讀寫互斥
  • StampedLock:樂觀讀、更高並發
  • AtomicLong/LongAdder:無鎖計數器
  • ConcurrentHashMap:分段鎖/CAS 無鎖 Map

最佳實踐清單

  1. 優先用 java.util.concurrent 高級組件,減少手寫 synchronized
  2. 鎖粒度越小越好,但避免過度優化
  3. 用 private final Object lock = new Object() 封裝鎖
  4. 固定多鎖獲取順序(如按 hashCode 排序)防死鎖
  5. 臨界區內避免 IO、網絡、sleep 等阻塞操作
  6. 讀多寫少場景用 ReadWriteLock 或 StampedLock

理解 synchronized 底層機制,是排查死鎖、活鎖、性能抖動的基礎。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved