2

看到下面的代碼,這讓我感到困惑,在類DynamicPropertyFactory中,它鎖定了ConfigurationManager.class,正如我的理解,鎖只能在類或實例本身中使用。如何理解這一點?使用同步鎖時感到困惑

public class *DynamicPropertyFactory*{ 
     public static *DynamicPropertyFactory* initWithConfigurationSource(AbstractConfiguration config) { 
      synchronized (**ConfigurationManager.class**) { 
       if (config == null) { 
        throw new NullPointerException("config is null"); 
       } 
       if (ConfigurationManager.isConfigurationInstalled() && config != ConfigurationManager.instance) { 
        throw new IllegalStateException("ConfigurationManager is already initialized with configuration " 
          + ConfigurationManager.getConfigInstance()); 
       } 
       if (config instanceof DynamicPropertySupport) { 
        return initWithConfigurationSource((DynamicPropertySupport) config); 
       } 
       return initWithConfigurationSource(new ConfigurationBackedDynamicPropertySupportImpl(config)); 
      } 
     } 
    } 
+0

爲什麼你將'class'鎖定在第一位? – emotionlessbananas

+2

「鎖只能在課堂上或實例本身中使用」這裏不清楚你的意思。 –

+0

還要注意''synchronized''不能「鎖定」任何東西。它*獲取對象監視器上的獨佔鎖(在本例中爲'ConfigurationManager.class'),以防止同時運行同一個鎖的多個同步方法或塊。 – Kayaman

回答

1

我的理解,鎖定只能在類或實例本身

這是錯誤的,不清楚你想說的話。

可以對任何未指向null的引用進行鎖定。

synchronized (ConfigurationManager.class) 

此行意味着在class上正在進行對象鎖定。

+0

對不起我的英文不好。我不明白爲什麼DynamicPropertyFactory類使用與另一個類同步,大多數情況下,我編寫的代碼如公共類* DynamicPropertyFactory * {public static * DynamicPropertyFactory * initWithConfigurationSource(AbstractConfiguration config){ synchronized(this){}} – lawrence

0

在這種情況下鎖定ConfigurationManager.class像全局監視器一樣工作。

如果你把相同的鎖中ConfigurationManager實例那麼 將同步所有線程,其處理的ConfigurationManager每個實例。

+0

但是,這是什麼使用類DynamicPropertyFactory,它不能與DynamicPropertyFactory類或其實例上的線程同步 – lawrence

+0

想象一下ConfigurationManager。類是靜態/常量/全局監視器,以防止其塊上的任何異步性能。 不幸的是我的英語能力也差。而我無法解釋另一種方式) –

0

This question是高度相關的;請記住,您的synchronized(target)的目標是管理代碼塊的相互排斥性。根據目標監視器是否被鎖定,只有一個線程可以在任何給定時間執行代碼塊,但目標不一定總是相同的對象。

無論你在代碼中提到的ConfigurationManager.class都應該解析爲同一個對象,所以它應該作爲一個通用鎖。但是,使用諸如synchronized(this)之類的東西與多個實例結合使用會導致每個實例的鎖定,並且某些功能可以讓這些代碼在這些實例中並行運行,而不會在任何單個實例上並行運行。

鎖定.class被認爲是不好的做法,您應該選擇類似private static final Object lock = new Object();的東西,而不是,如果您確實必須擁有全局鎖定。

+0

看起來理解的東西,當你閱讀你的文章,應該閱讀更多的時間。謝謝。 – lawrence