Is it optimal to use a double proven locking idiom for a singleton pattern?

Is it better to use a double verified idiom lock for a singleton pattern? Or a synchronized method?

t

private static volatile ProcessManager singleton = null; public static ProcessManager getInstance() throws Exception { if (singleton == null) { synchronized (MyClass.class) { if (singleton == null) { singleton = new ProcessManager(); } } } return singleton; 

}

or

 private static processManager singleton = null; public synchronized static processManager getInsatnce() throws Exception { if(singleton == null) { singleton = new processManager(); } return singleton } 
+6
source share
5 answers

Ask ClassLoader to do the job for you:

  /* * This solution takes advantage of the Java memory model guarantees about class initialization * to ensure thread safety. Each class can only be loaded once, and it will only be loaded when it * is needed. That means that the first time getInstance is called, mySingletonServiceLoader * will be loaded and instance will be created, and since this is controlled by ClassLoaders, * no additional synchronization is necessary. */ public static DocumentService getInstance() { return mySingletonServiceLoader.INSTANCE; } private static class mySingletonServiceLoader { static DocumentService INSTANCE = new DocumentService(); } } 
+6
source

Basically, your second option does not add an additional guarantee.

You often check, but parallel access is possible between them, so you reduce the likelihood of two instances, but do not eliminate it.

0
source

First option.

It is possible to create multiple versions of one instance ...

in the call to getInstance (), the instance is checked for null , and then immediately created if it is zero, and then instance returned.

It must be thread safe.

Refer to this .

0
source

The first option is the correct implementation of the double check lock, but if there are no more public methods in the ProcessManager class and getInstance, then you need only

 public class ProcessManager { private static ProcessManager instance; static { instance = new ProcessManager(); } private ProcessManager() { } public static ProcessManager getInstance() { return instance; } } 

the class will be loaded and initialized the first time ProcessManager.getInstance () is called

0
source

If lazy loading is required , I would stick with a double check instead of a synchronized method. In the end, the problem is volatile vs. synchronized :

Volatile, simply forces all accesses (read or write) to the volatile variable to go to main memory, effectively storing the volatile variable from the CPU caches. This can be important for some actions, when it is just required that the variable is visible and the access order is not important.

After the instance is initialized, the synchronized block will not be executed (but for race conditions). The only concurrency cost to pay is a one-time reading of the volatile variable.

Note that Effective Java Bloch says loading a volatile field into a local variable improves performance (I understand this because the number of volatile reads is less)

  public static ProcessManager getInstance() throws Exception { ProcessManager result = singleton; if (result == null) { synchronized (MyClass.class) { result = singleton; if (result == null) { singleton = result = new ProcessManager(); } } return result; } 
0
source

All Articles