Search code examples
javamultithreadingthread-safetylazy-initialization

Single- and double-check lazy initialization


I can't understand piece of code in Item 71 in 'Effective Java' about the Double-check idiom and the single-check idiom for lazy initialization of instance fields:

Double-check idiom

private volatile FieldType field;
FieldType getField() {
  FieldType result = field;
  if (result == null) {
    synchronized(this) {
      result == field;
      if (result == null)
        field = result = computeFieldValue();
    }
  }
  return result;
}

Single-check idiom

private volatile FieldType field;
FieldType getField() {
  FieldType result = field;
  if (result == null) {
    field = result = computeFieldValue();
  }
  return result;
}

We use locking in first case, as i understand, in order to compute FieldValue() performed atomically. But why we omit it in second case? Because now some alien thread could corrupt some value that take part in computation. What i missed?


Solution

  • The point of double-checked locking is that it ensures that computeFieldValue is invoked only once, and the field written to only once.

    There are cases where it is acceptable to call this method more than once, making double-checked locking an overkill. These are some of the conditions to meet:

    • computeFieldValue should be a pure function, always returning the same value;
    • the magnitude of the risk of it being called more than once is acceptable (chances of that happening multiplied by its performance impact).