Versions Compared

Key

  • This line was added.
  • This line was removed.
  • Formatting was changed.
Comment: trying to make the introductory description flow a little better. also cleaned up some of the description around the new nce/s example.

The double-checked locking idiom is a software design pattern used to reduce the overhead of acquiring a  lock by first testing the locking criterion without actually acquiring the lock. Double-checked locking improves performance by limiting synchronization to the rare case of computing the field's value or constructing a new instance for the field to reference and by foregoing synchronization during the common case of retrieving an already-created instance or value.

Incorrect forms of the double-checked locking idiom include those that allow publication of an uninitialized or partially initialized object. Consequently, only those forms of the double-checked locking idiom that correctly establish a happens-before relationship both for the helper reference and for the complete construction of the Helper instance are permitted.

The double-checked locking idiom is frequently used to implement a Singleton Factory pattern that performs lazy initializationLazy initialization defers the construction of a member field or an object referred to by a member field until an instance is actually required rather than computing the field value or constructing the referenced object in the class's constructor. Lazy initialization helps to break harmful circularities in class and instance initialization . It also enables other optimizations [Bloch 2005].

...

Code Block
bgColor#ccccff
// Correct multithreaded version using synchronization
final class Foo {
  private Helper helper = null;

  public synchronized Helper getHelper() {
    if (helper == null) {
      helper = new Helper();
    }
    return helper;
  }
  // ...
}

The double-checked locking idiom improves performance by limiting synchronization to the rare case of computing the field's value or constructing a new instance for the field to reference and by foregoing synchronization during the common case of retrieving an already-created instance or value.

Incorrect forms of the double-checked locking idiom include those that allow publication of an uninitialized or partially initialized object. Consequently, only those forms of the double-checked locking idiom that correctly establish a happens-before relationship both for the helper reference and for the complete construction of the Helper instance are permitted.

 

Noncompliant Code Example

...

In this noncompliant code example, we modify the  the Helper class to be is made immutable , by declaring its fields final. The Java Memory Model (JMM) guarantees that immutable objects are fully constructed before they become visible to any other thread. The block synchronization in the getHelper() method suffices to ensure method guarantees that all threads that can see a non-null value of the helper field will see the fully-initialized Helper object.

Code Block
bgColor#ffcccc
langjava
public final class Helper {
  private final int n;
 
  public Helper(int n) {
    this.n = n;
  }
 
  // Other fields and methods, all fields are final
}
 
final class Foo {
  private Helper helper = null;
 
  public Helper getHelper() {
    if (helper == null) {            // 1stFirst read of helper
      synchronized (this) {
        if (helper == null) {        // 2ndSecond read of helper
          helper = new Helper(42);
        }
      }
    }
    return helper;                   // 3rdThird read of helper
  }
}

However, this code is still unsafe on some not guaranteed to be succeed on all JVM platforms . This occurs because there is no happens-before relationships on the 1st read or the 3rd between the first read and third read of helper. ThereforeConsequently, it is possible for the 3rd third read of helper to obtain a stale null value of null (perhaps because its value was cached or reordered by the compiler) . In other words, a call to causing the getHelper() can method to return a null pointer.

Compliant Solution (Immutable)

This compliant solution uses a local variable to reduce the number of reads of the helper field to 1. ThereforeAs a result, if the read of helper yields a non-null value, it is cached in a local variable that is inaccessable to other threads, and safely returned.

...