6

Is it better to use the double checked locking idiom for a singleton pattern? Or a synchronised method?

ie:

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
 }
Pectus Excavatum
  • 3,593
  • 16
  • 47
  • 68
  • Having two nested ifs without anything in between, as in your second piece of code, makes no sense. – Jesper Mar 20 '13 at 14:52
  • 4
    None of the above, as explained in [this answer](http://stackoverflow.com/a/15498689/1103872) to your own previous question. – Marko Topolnik Mar 20 '13 at 14:52
  • in your second example, the double check is not needed (assuming you're not touching the singleton member anywhere else in your class) since you're already in the critical section – Grimmy Mar 20 '13 at 14:54
  • 2
    @a_horse_with_no_name No, it doesn't, even after taking into account threading issues. – Marko Topolnik Mar 20 '13 at 14:54
  • I read somewhere, don't remember where, the best way to initialize singleton is to initialize it statically. In this case, `private static processManager singleton = new processManager()` – anoopelias Mar 20 '13 at 14:55
  • possible duplicate of [What is an efficient way to implement a singleton pattern in Java?](http://stackoverflow.com/questions/70689/what-is-an-efficient-way-to-implement-a-singleton-pattern-in-java) Number three in a Google search for "java singleton". – Christoffer Hammarström Mar 20 '13 at 14:56
  • @MarkoTopolnik: I was looking at the first piece of code... (need to get some coffee) –  Mar 20 '13 at 14:57
  • @anoopelias Naturally, if you can afford eager initialization, the best option is a `static final` field for the singleton. – Marko Topolnik Mar 20 '13 at 15:07
  • In short, implement singletons using `enum`, if you must make it a singleton. – Christoffer Hammarström Mar 20 '13 at 15:10

5 Answers5

6

Have the ClassLoader do the job for you :

    /*
     * This solution takes advantage of the Java memory model's 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();
    }
}
LaGrandMere
  • 10,265
  • 1
  • 33
  • 41
0

Basically, your second option adds no additional guarantee.

You check more often, but concurrent access can still occur between them, so, you're diminishing the probability of two instances occurring, but not eliminating it.

pcalcao
  • 15,789
  • 1
  • 44
  • 64
0

First option.

There is the ability to create multiple versions of the single instance...

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

It should be thread safe.

Refer this also.

Community
  • 1
  • 1
Suresh Atta
  • 120,458
  • 37
  • 198
  • 307
0

The first option is correct double-checked locking implementation, but if there is no more public methods in ProcessManager class but getInstance then all you need is

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 on first ProcessManager.getInstance() invocation

Evgeniy Dorofeev
  • 133,369
  • 30
  • 199
  • 275
0

If lazy-load is required, I would adhere to the double-check instead of a synchronized method. In the end, the issue is that of volatile vs. synchronized:

Volatile, simply forces all accesses (read or write) to the volatile variable to occur to main memory, effectively keeping the volatile variable out of CPU caches. This can be important for some actions where it is simply required that visibility of the variable be correct and order of accesses is not important.

Once the instance has been initialized, the synchronized block will not be executed (but for race conditions). The only concurrency cost to be paid is that of a single read to the volatile variable.

Note that in Effective Java Bloch says that loading the volatile field in a local variable enhances performance (I understand that is because there are fewer volatile reads)

 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;
}
Community
  • 1
  • 1
Javier
  • 12,100
  • 5
  • 46
  • 57