Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Double checked locking pattern: Broken or not?

Why is the pattern considered broken? It looks fine to me? Any ideas?

public static Singleton getInst() {
    if (instace == null) createInst();
    return instace;
}

private static synchronized createInst() {
     if (instace == null) {
         instace = new Singleton(); 
     }
}
like image 989
fastcodejava Avatar asked Sep 01 '10 09:09

fastcodejava


People also ask

Can double-checked locking fail?

Double-Checked Locking is widely cited and used as an efficient method for implementing lazy initialization in a multithreaded environment. Unfortunately, it will not work reliably in a platform independent way when implemented in Java, without additional synchronization.

Is double-checked locking safe?

Since only the first access requires locking, double-checked locking is used to avoid locking overhead of subsequent accesses. However, on many languages and hardware, the design can be unsafe.

How do I stop double check locking?

The only way to do double-checked locking correctly in Java is to use "volatile" declarations on the variable in question. While that solution is correct, note that "volatile" means cache lines get flushed at every access.

Can the double-checked locking fail on single processor system?

Ans. There is no mapping of single ton with number of processor of the system. So double check locking will not fail depending on number of processor.


1 Answers

It looks okay at first glance, but this technique has many subtle problems and should usually be avoided. For example, consider the following sequence of events:

  1. Thread A notices that the value is not initialized, so it obtains the lock and begins to initialize the value.
  2. The code generated by the compiler is allowed to update the shared variable to point to a partially constructed object before A has finished performing the initialization.
  3. Thread B notices that the shared variable has been initialized (or so it appears), and returns its value. Because thread B believes the value is already initialized, it does not acquire the lock. If B uses the object before all of the initialization done by A is seen by B the program will likely crash.

You could avoid this by using the "volatile" keyword to handle your singleton instances correctly

like image 168
Jeroen Rosenberg Avatar answered Oct 01 '22 21:10

Jeroen Rosenberg