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

Java synchronized 關鍵字深度解析:鎖對象、作用域與併發陷阱實戰驗證

     編輯:Java 綜合教學

核心原理:synchronized 鎖的是「對象監視器」

  • 實例方法:鎖 this(當前對象)。
  • 靜態方法:鎖 ClassName.class(類對象)。
  • 同步代碼塊:鎖 synchronized(obj) 指定的對象。
同一把鎖(同一對象監視器)同一時刻只能被一個線程持有。不同鎖互不影響。

實戰驗證:類鎖 vs 對象鎖互不干擾

public class Printer {
    // 靜態同步方法 → 鎖 Printer.class
    public static synchronized void printA() {
        log("printA start");
        sleep(1000);
        log("printA end");
    }

    // 實例同步方法 → 鎖 this
    public synchronized void printB() {
        log("printB start");
        sleep(1000);
        log("printB end");
    }

    // 普通方法 → 無鎖
    public void printC() { log("printC"); }

    private void log(String msg) {
        System.out.println(Thread.currentThread().getName() + " " + msg);
    }
    private void sleep(int ms) { try { Thread.sleep(ms); } catch (InterruptedException ignored) {} }
}

測試場景 1:兩線程分別調用 printA (靜態) 和 printB (實例)

Thread-A: printA start
Thread-A: printA end
Thread-B: printB start
Thread-B: printB end
// 或交替輸出,關鍵是:printA 和 printB 可並發執行,因為鎖對象不同(Printer.class vs this)

測試場景 2:同一實例並發調用 printB

Thread-1: printB start
Thread-1: printB end
Thread-2: printB start  // 必須等待 Thread-1 釋放 this 鎖
Thread-2: printB end

測試場景 3:printC (無鎖) 與 printB 並發

Thread-1: printC
Thread-2: printB start
Thread-2: printB end
Thread-1: printC
// printC 不受 printB 鎖影響,隨時可執行

同步代碼塊靈活控制鎖粒度

public void syncBlockDemo(Object lock) {
    System.out.println("非同步代碼..."); // 無鎖
    synchronized (lock) { // 僅鎖住關鍵區
        // 臨界區操作
    }
    System.out.println("非同步代碼..."); // 無鎖
}

常見併發陷阱與避坑

陷阱現象修正
鎖字符串常量synchronized("lock") 常量池共享,非預期全局互斥用 new Object() 或 this / Class.class
鎖基本類型包裝對象synchronized(Integer.valueOf(1)) 緩存池導致不同實例共用鎖用 new Integer(1) 或專用鎖對象
同步方法中調用異步/耗時操作長時間持有鎖,吞吐率暴跌縮小同步塊範圍,異步操作移出同步塊
死鎖線程 A 鎖 1 等 2,線程 B 鎖 2 等 1固定加鎖順序、tryLock 超時、避免嵌套鎖

JVM 優化:偏向鎖 → 輕量級鎖 → 重量級鎖

  • JDK 1.6+ 引入鎖升級機制:無鎖 → 偏向鎖(單線程重複獲取) → 輕量級鎖(CAS,低併發) → 重量級鎖(OS 互斥量,高併發)。
  • synchronized 性能已接近 ReentrantLock,優先選擇 synchronized(代碼簡潔、JVM 原生支持、逃逸分析可消除鎖)。
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved