Singleton non-volatile

Say I have the following class:

public class Singleton{

  private static Singleton _instance; 

  public static Singleton getInstance(){

   if(_instance == null){
         synchronized(Singleton.class){
           if(_instance == null)
           _instance = new Singleton();
         }
   }
   return _instance;
 }

For example, we have two threads A and B that try to execute the getInstance () method at the same time. I correctly understood the process:


  • Thread A enter the getInstance () method and acquire a lock;
  • Thread B also introduces the getInstance () method and blocks;
  • Thread Create a new Singleton () object and release the lock, now the last value of the _instance variable should be visible for thread B? Or can thread B still have its own copy of the _instance variable, which is not synchronized with main memory (_instance = null)?
+4
source share
3 answers

B , , _instance != null , , , .

, , , .

: , volatile, , , ( , ), .

Java , . ,

  • (JLS 17.4.5)
  • (JLS 12.4)
  • volatile (JLS 17.4.5) , AtomicX
  • (JLS 17.5).

( , ) - , ( ), JVM:

class Singleton
{
    private static final Singleton HIGHLANDER = new Singleton();
    private Singleton() { } // not accessible
    public static getSingleton() { return HIGHLANDER; }
}

JDK "Holder" , :

class Singleton
{
    private Singleton() { } // not accessible
    private static Class LazyHolder {
        private static final Singleton LAZY_HIGHLANDER = new Singleton();
    }
    public static Singleton getInstance() {
        return LazyHolder.LAZY_HIGHLANDER;
    }
}

volatile ( DCL) ( JVM, ).

+4

, , .

, . , , , . volatile.

, Java 5 . , . , . Java.

+3

Two problems that may exist, as far as I know. Thread B may or may not see the last value. Thread B can see the partially constructed object if there are many things that the constructor does, and the JVM decides to reorder the code.

Ensuring its volatility solves both problems, since it ensures that events are executed before the relationship and stops the JVM from ordering code execution and updates values ​​in other threads.

+1
source

All Articles