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

Java 靜態同步方法 vs 實例同步方法:是否互斥?

     編輯:程式設計綜合問答

代碼

class Test {
    synchronized static void sayHello3() { }
    synchronized void getX() { }
}

結論:不互斥,可同時執行。

原因:鎖對象不同

方法類型鎖對象範圍
static synchronizedTest.class (Class 物件)全進程、所有實例共享
synchronized (實例方法)this (具體實例)單一實例

Test.class 與 this 是兩個完全不同的物件,Java 監視器機制依據物件身分互斥,故兩把鎖互不干擾。

驗證程式

public class SyncDemo {
    static final Object STATIC_LOCK = Test.class;
    static final Object INSTANCE_LOCK = new Test();

    public static void main(String[] args) {
        new Thread(() -> {
            synchronized (STATIC_LOCK) {
                System.out.println("靜態方法開始");
                sleep(1000);
                System.out.println("靜態方法結束");
            }
        }).start();

        new Thread(() -> {
            synchronized (INSTANCE_LOCK) {
                System.out.println("實例方法開始");
                sleep(1000);
                System.out.println("實例方法結束");
            }
        }).start();
    }
    static void sleep(long ms) { try { Thread.sleep(ms); } catch (InterruptedException ignored) {} }
}

輸出會交錯顯示「靜態方法開始」→「實例方法開始」→...,證明並行執行。

進階:若要互斥怎麼辦?

  • 統一使用同一把鎖:private static final Object LOCK = new Object(); 兩方法皆 synchronized(LOCK)。
  • 或將實例方法改為 static synchronized(但失去實例隔離性)。

最佳實踐

  1. 優先使用 java.util.concurrent.Lock (ReentrantLock) 顯式管理鎖,語意更清晰。
  2. 縮小同步塊範圍:synchronized(lock) { /* 只保護共享狀態 */ },不要鎖整個方法。
  3. 避免混用靜態/實例同步,除非刻意設計為不同保護層級。

理解「鎖的是物件,不是代碼」是 Java 併發編程的基石。

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