Why is Java Double Detected Locking (DCL) not recommended?

refer to

    "Java Concurrent Programming in Practice" 286 pages

Why use DCL:

    Early JVM performance needs to be optimized, and delayed initialization can avoid high overhead (reinitialization when used), or reduce program startup time. Lazy initialization requires the use of synchronization, but synchronization is slow to execute . Therefore, it is first judged by asynchronous (one time is null, then new, so it is basically not null later), so that most of the cases when it is not null will not be time-consuming. When waiting for new, atomicity must be guaranteed , so add a lock.

public static Singleton getInstance()
{
  if (instance == null)
  {
    synchronized(Singleton.class) {  //1
      if (instance == null)          //2
        instance = new Singleton();  //3
    }
  }
  return instance;
}

question:

1. Visibility

    Thread safety: atomicity, visibility . Atomicity is guaranteed, but visibility is not considered.

    Visibility is simply: if thread a changes data, thread b may not see it. The a thread has its own cache (CPU cache 1), and the b thread also has its own (CPU cache 2). The CPU cache maintains consistency by reading and writing memory. In other words, thread b has new object y, and y has just started to be in CPU cache 2, and needs to be written to memory. CPU cache 1 reads into the memory update cache, and thread a can see the y object.

    So the instance object is released by thread a, instance == null, and thread b may look at instance != null;

2. Partial initialization

    Maybe the instance in the a thread points to the memory address of the object, but the constructor has not yet gone (the instructions for the new object cpu are separated, normally 1. Allocate memory 2. Initialize the object (memory assignment) 3. Assign the memory address to the instance But CPU instructions may be optimized and reordered, 3 runs before 2),

    So its property is the invalid state. The b thread judges that instance != null to directly call instance.hello, because every time the instance constructor is called, it may be null and it crashes directly.


solve:

    Declare singleton objects as volatile, fix visibility, ordering


Why DCL was abandoned:

    The reasons for DCL (the slow execution of uncontended synchronization, and the slow JVM startup) no longer exist and are therefore not efficient optimizations.

        


    


Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=324672857&siteId=291194637