2008-11-24 25 views
3

我有一個類,它看起來是這樣的:靜態成員需要特殊的同步塊嗎?

public class Test { 

private static final Object someObject = new Object(); 

public void doSomething() 
{ 
    synchronized (someObject) { 
     System.out.println(someObject.toString()); 
    } 
} 

} 

我可以考慮要同步的對象,或者是有一個問題,因爲它是一個靜態成員?

編輯:注意,不同的線程可能正在訪問DoSomething的()和對象必須在這種情況下,一個線程安全的方式來訪問。

回答

7

通過使用靜態對象作爲監視器對象,只有一個使用ANY實例的Test類的線程可以進入同步塊。如果監視器對象不是靜態對象,則其他保持Test類不同實例的線程可以進入同步塊。

+0

我不明白。這是否意味着代碼片段就像我期待的那樣工作? – 2008-11-24 16:21:20

4

這裏someObject充當鎖(監視器)所有類型Test的對象。也就是說,如果在兩個單獨的Test實例上調用doSomething(),則會在另一個完成之前阻塞。這與同步方法不同,後者大部分與上述代碼相同,someObject取代

更改爲非靜態的someObject將導致每個實例的鎖定。這實質上就是的第70項中描述的「私人鎖定對象」慣用語,有效的Java

1

用於獲取一個特定的類實例無關的鎖像這樣的常見模式是使用類對象本身:

public class Test { 
    public void doSomething() { 
    synchronized (Test.class) { 
     // something 
    } 
    } 
} 

這是有效地同步的靜態方法做什麼。當然,如果你想要這樣一個以上的鎖,你需要將它們聲明爲靜態字段,就像你的例子。

0

如果使用不同的類加載器加載測試類,會發生什麼情況?