2

See below code, this puzzles me, in class DynamicPropertyFactory, it locks ConfigurationManager.class, as my understanding, the lock works only in the class or the instance itself. How to understand this?

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));
            }
        }
    }
lawrence
  • 353
  • 2
  • 17
  • why you locking `class` in first place? – bananas Aug 02 '16 at 07:23
  • 2
    "the lock works only in the class or the instance itself" It's unclear what you mean here. – Andy Turner Aug 02 '16 at 07:27
  • Also note that `synchronized` does not "lock" anything. It *acquires* an exclusive lock on an object's monitor (in this case `ConfigurationManager.class`) preventing multiple synchronized methods or blocks that use the same lock to run at the same time. – Kayaman Aug 02 '16 at 07:29
  • You synchronize against the ConfigurationManager.class object. That does not mean all methods inside that class do so. only if they too use the synchronized keyword or acquire a lock on the class object. – Fildor Aug 02 '16 at 07:30
  • A Class is a (singleton) object too. It might be that that class has synchronized methods, the above synchronisation wants to synchronize with them too. Quite ugly of course. – Joop Eggen Aug 02 '16 at 07:58
  • Your code is entirely equivalent to making the method itself synchronized. Do you understand that? – user207421 Aug 02 '16 at 09:51

3 Answers3

1

as my understanding, the lock works only in the class or the instance itself

This is wrong and unclear what you want to say.

lock can be taken on any reference which is not pointing to null.

synchronized (ConfigurationManager.class)

this line means that on class object lock is being taken.

Azodious
  • 13,752
  • 1
  • 36
  • 71
  • sorry for my poor english. I do not understand why DynamicPropertyFactory class using synchronized with another class, mostly, I write code like public class *DynamicPropertyFactory*{public static *DynamicPropertyFactory* initWithConfigurationSource(AbstractConfiguration config) { synchronized (this) {}} – lawrence Aug 02 '16 at 09:11
0

In this case lock on ConfigurationManager.class works like global monitor.

If you put the same lock in to ConfigurationManager instance then it will synchronize all threads, which deal each instance of ConfigurationManager.

  • But what does this to do with class DynamicPropertyFactory, it cannot be synchronized with threads on DynamicPropertyFactory class or its instance – lawrence Aug 02 '16 at 09:13
  • Imagine that ConfigurationManager.class are static/constant/global monitor for prevent any async performance on its block. Unfortunately my English skills also to poor. And i can't explain another way ) – Igor Perciuleac Aug 02 '16 at 09:19
0

This question is highly relevant; remember that the target of your synchronized(target) is the thing that manages the mutual exclusivity of the code block. Only one thread can execute the code block at any given time, based on whether the monitor of the target is locked, but the target isn't necessarily always the same object.

Everywhere you refer to ConfigurationManager.class in your code should resolve to the same object, so it should work as a universal lock. However, using something like synchronized(this) combined with many instances would result in a lock per instance and some ability for that code to be run in parallel across those instances, just never in parallel on any single instance.

Locking on .class is considered bad practice and you should opt for something like private static final Object lock = new Object(); instead, if you really must have a global lock.

Community
  • 1
  • 1
Danikov
  • 735
  • 3
  • 10