簡體   English   中英

在類對象上同步

[英]Synchronization on class object

當我閱讀以下示例時,我正在閱讀有關並發性的教程:

這是與靜態方法相同的兩個示例。 這些方法在方法所屬的類的類對象上同步:

    public class MyClass {

    public static synchronized void log1(String msg1, String msg2){
       log.writeln(msg1);
       log.writeln(msg2);
    }


    public static void log2(String msg1, String msg2){
       synchronized(MyClass.class){
          log.writeln(msg1);
          log.writeln(msg2);  
       }
    }
  }

在同一時間,這兩個方法中的任何一個都只能執行一個線程。

如果第二個同步塊已在與MyClass.class不同的對象上同步,則一個線程可以在每個方法中同時執行。

我只想確保我做對了。

因此,您不能在單個線程中同時調用方法log1和log2嗎? 但是,如果同步對象不在類對象上,您可以嗎?

我猜更多是翻譯困擾着我。

一個帶有注釋的例子值得贊賞。

否。這兩個方法都在MyClass.class上同步。 因此,如果一個線程調用任何一個方法,則另一個線程無法同時調用這兩個方法中的任何一個。

如果一個方法在另一個對象上同步,則這兩個方法不再互斥,一個線程可以調用log2,而另一個線程調用log1。

因此,您不能在單個線程中同時調用方法log1和log2嗎? 但是,如果同步對象不在類對象上,您可以嗎?

確切地說,您不能同時在不同的線程中調用方法log1和log2。 聲明static synchronized的方法與在類對象上static synchronized具有相同的效果。

這是第二個方法在log變量而不是類上同步的示例。

public class MyClass {

  public static synchronized void log1(String msg1, String msg2){
    log.writeln(msg1);
    log.writeln(msg2);
  }

  public static void log2(String msg1, String msg2){
    synchronized(log){
      log.writeln(msg1);
      log.writeln(msg2);  
    }
  }

}

在這種情況下,兩個單獨的線程可以同時執行log1log2 ,因為它們在不同的對象上進行同步: MyClass.class對象上的log1log對象上的log2 (無論在何處定義)。

這是關於同步方法和塊要記住的關鍵事項:

  1. 同步的代碼必須在所有線程之間使用相同的對象實例進行同步。
  2. 類也是對象! 通常只有給定Class對象的一個​​實例,該實例是在首次加載該類時創建的。

因此,您不能在單個線程中同時調用方法log1和log2嗎?

您不能從單個線程中同時調用任何兩個方法。 您可以同時從一個線程和另一個線程調用相同的方法。

發生這種情況時(如果方法已同步),第一個獲得鎖(在您的情況下為MyClass.class )的線程將執行同步塊,然后釋放鎖。 只有在另一個線程之后,它才能嘗試獲取該鎖並繼續執行。

您有2個方法都在MyClass.class同步。 這意味着,如果第一個線程獲得MyClass.class鎖定(可以通過調用log1log2對其進行點綴),則第二個線程,如果他想要執行MyClass.class鎖定的任何操作(在您的情況下為log1log2方法中的任何一個) ),必須等到第一個線程釋放此鎖才能執行。

但是,如果同步對象不在類對象上,您可以嗎?

這意味着其中一種方法在MyClass.class上同步,而另一種方法在其他方法上同步(對於非靜態默認值為this )。 它們具有不同的鎖,因此可以從不同的線程同時執行。

暫無
暫無

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

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