簡體   English   中英

同步塊中的靜態與非靜態鎖定對象

[英]Static versus non-static lock object in synchronized block

嘗試可視化和理解同步

  1. 同步塊使用靜態鎖定對象 (代碼A)非靜態鎖定對象 (代碼B)有什么區別?
  2. 它在實際應用中有何不同?
  3. 另一個不會有什么陷阱?
  4. 確定使用哪一個的標准是什么?

代碼A.

public class MyClass1 {
  private static final Object lock = new Object();
  public MyClass1() {
    //unsync
    synchronized(lock) {
      //sync
    }
    //unsync
  }
}

代碼B.

public class MyClass2 {
  private final Object lock = new Object();
  public MyClass2() {
    //unsync
    synchronized(lock) {
      //sync
    }
    //unsync
  }
}

注意

上面的代碼顯示了構造函數,但您可以在靜態方法和非靜態方法中討論行為的不同之處。 另外,當synchronized塊修改靜態成員變量時,使用靜態鎖是否有利?

我已經在這個問題中查看了答案,但不清楚不同的使用場景是什么。

區別很簡單:如果鎖定的對象在static字段中,那么MyClass*所有實例將共享該鎖(即,沒有兩個對象可以同時鎖定該對象)。

如果該字段是非靜態的,則每個實例都有自己的鎖,因此只有對同一對象的方法調用才會相互鎖定。

使用靜態鎖定對象時:

  • 線程1調用o1.foo()
  • 線程2調用o1.foo() ,必須等待線程1完成
  • 線程3調用o2.foo()必須等待線程1(可能還有2)完成

使用非靜態鎖定對象時:

  • 線程1調用o1.foo()
  • 線程2調用o1.foo() ,必須等待線程1完成
  • 線程3調用o2.foo() ,它可以繼續,而不是注意線程1和2

您需要哪一個取決於您嘗試使用synchronized塊保護的數據類型。

根據經驗,您希望鎖定對象具有與操作值相同的static 因此,如果操作非靜態值,則需要非靜態鎖定對象。 如果操作靜態值,則需要靜態鎖定對象。

當您操縱靜態和非靜態值時,它將變得復雜。 簡單的方法是使用靜態鎖定對象,但這可能會增加synchronized塊的大小,而不是絕對必要,並且可能需要比預期更多的鎖爭用。 在這些情況下,您可能需要靜態和非靜態鎖定對象的組合。

在您的特定情況下,您在構造函數中使用了鎖,每個實例只執行一次,因此非靜態鎖對象在這里沒有任何意義。

暫無
暫無

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

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