2015-01-10 114 views
1

「this」對象對於兩個線程是不同的,因爲它們是兩個不同的對象。因此,他們正在檢查兩個不同的鎖,因此也不應該在平行的一個關鍵部分停止投放:爲什麼synchronized(this)有效?

void method() { 
    synchronized(this) { 
     //critical section 
    } 
} 

我怎麼錯過?

+2

你錯過了很多。此語句引用線程輸入的業務對象。它與線程實例無關。 synchronized(this)一次只允許一個線程輸入該對象的代碼塊。 – tmn

回答

1

下面是一個例子,其中它是兩個線程相同的對象:)

class Test { 

    void method() { 
     synchronized(this) { 
     } 
    } 

    public static void main(String[] args) throws Exception { 
     final Test t1 = new Test(); 
     new Thread() { 
      public void run() { 
       t1.method(); 
      }; 
     }.start(); 
     new Thread() { 
      public void run() { 
       t1.method(); 
      }; 
     }.start(); 
    } 
} 
+0

你的例子說得很清楚,我認爲「this」是Thread對象,因爲我讀的文章只提供了一小段代碼。 – huehuehuehue

0

你不會錯過任何東西。如果您的線程嘗試應用​​並嘗試鎖定兩個不同對象的監視器,則它們不會彼此阻塞。

2

如果您有一個關鍵部分,它通常涉及單個對象。在這些情況下,如果兩個不同的實例並行運行,則不存在競爭條件,假設它們只處理實例本地資源(例如專用字段)。

您可能錯過的是,如果同一類型的對象在共享資源上工作,synchronized(this)確實不會阻止它們並行訪問它。在這種情況下,您可以使用synchronized(MyFoo.class) { }或共享變量對類本身進行同步。

+0

感謝提示 – huehuehuehue

0

Java中的每個對象都有一個鎖機制,一次只能有一個線程佔用鎖。當用同步(this)包圍代碼塊或向方法添加同步關鍵字時,它只會將一個線程限制爲該對象的同步區域。它與線程實例無關,同一類的兩個實例也不共享鎖。

0

如果同一對象的多個線程調用方法(;那麼一次只有一個線程會獲得對象的監視器。但如果有不同 - 同一類型的不同對象,則它們可以並行輸入。

當你有任何類變量時,這個代碼中唯一的問題就會發生,所以當你必須使用類級鎖時,共享這個代碼。

相關問題