Versions Compared

Key

  • This line was added.
  • This line was removed.
  • Formatting was changed.

...

Code Block
bgColor#ccccff
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() {
    Helper h = helper;       // Only unsynchronized read of helper
    if (h == null) {
      synchronized (this) {
        h = helper;          // In synchronized block, so this is safe
        if (h == null) {
          h = new Helper(42);
          helper = h;
        }
      }
    }
    return h;
  }
}

Exceptions

LCK10-J-EX0: Use of the noncompliant form of the double-checked locking idiom is permitted for 32-bit primitive values (for example, int or float) [Pugh 2004], although this usage is discouraged. The noncompliant form establishes the necessary happens-before relationship between threads that see an initialized version of the primitive value. The second happens-before relationship (for the initialization of the fields of the referent) is of no practical value because unsynchronized reads and writes of primitive values up to 32-bits are guaranteed to be atomic. Consequently, the noncompliant form establishes the only needed happens-before relationship in this case. Note, however, that the noncompliant form fails for long and double because unsynchronized reads or writes of 64-bit primitives lack a guarantee of atomicity and consequently require a second happens-before relationship to guarantee that all threads see only fully assigned 64-bit values (see  VNA05-J. Ensure atomicity when reading and writing 64-bit values for more information).

...