Double-checked locking

https://www.securecoding.cert.org/confluence/display/java/LCK10-J.+Use+a+correct+form+of+the+double-checked+locking+idiom

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.

Compliant variants:

Using mutable:
// Works with acquire/release semantics for volatile
// Broken under JDK 1.4 and earlier
final class Foo {
  private volatile Helper helper = null;
  public Helper getHelper() {
    if (helper == null) {
      synchronized (this) {
        if (helper == null) {
          helper = new Helper();
        }
      }
    }
    return helper;
  }
}
Static Initialization:
final class Foo {
  private static final Helper helper = new Helper();
  public static Helper getHelper() {
    return helper;
  }
}

Immutable:

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;
  }
}