簡體   English   中英

Java同步:如果將Java中的多個方法設為原子/同步,那么是否同時將鎖定應用於所有這些方法?

[英]Java synchronization: If more than one methods in java are made atomic/synchronized, is the lock applied to all of them at the same time?

假設我的Java代碼中有2個同步方法:

    public class SynchronizedCounter {
    private int c = 0;

    public synchronized void increment() {
        c++;
    }

    public synchronized void decrement() {
        c--;
    }

    public synchronized int value() {
        return c;
    }
}

假設我有2個操作線程:t1和t2。 如果t1正在使用increment()方法並中途進入睡眠狀態,則由於鎖定,t2將無法在increment()方法上進行操作。 我的問題是t2能夠對decrement()和value()進行操作,還是與某個對象關聯的所有同步方法在線程訪問其中一個同步方法后立即被鎖定?

靜態同步方法呢?

同步實例方法將對象實例用作鎖。 沒有兩個線程可以同時使用相同的對象輸入這些方法。 如果t1和t2在同一對象上操作,則t2將被阻止,直到t1釋放鎖定。

對於靜態同步方法,將鎖放置在包含方法的類的Class對象上。

您可以在並發教程中閱讀有關鎖定的更多信息,但是本質上來說,靜態方法和非靜態方法之間的區別是被鎖定的對象。 此類中的方法聲明:

class Test {
  synchronized void methodA() { ... }
  static synchronized void methodB() { ... }
}

等效於此處的方法聲明:

class Test {
  void methodA() { 
    synchronized (this) {
        ...
    }
  }
  static void methodB() { 
    synchronized (Test.class) {
        ...
    }
  }
}

文檔動作指出:“當一個線程正在執行對象的同步方法時,所有其他線程調用同一對象的同步方法(掛起執行),直到第一個線程完成該對象為止。”你的問題。

當您將一個方法聲明為已同步時,該實例對象將被視為鎖。

同步方法在它們所在的類的實例的鎖上進行操作。因此,簡而言之:如果t1睡在increment()任何線程都無法訪問任何synchronized方法。

此外,您所截取的代碼與Java教程中的示例相同,該示例也提供了答案...

對象的所有同步實例方法共享由該對象實現的相同鎖。 所有靜態同步方法共享相同的鎖,由類對象實現。

如果需要更細粒度的鎖定,則需要使用同步塊和單獨的鎖定對象,即

private Object decrementLock = new Object();
public void decrement() {
    synchronized(decrementLock){
        c--;
    }
}

當然,在這種情況下,這將使同步失敗,並導致數據損壞。

鎖與對象關聯,而不與線程關聯。 超過1個線程可以訪問同步方法,但是調用方法的對象應該不同。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM