← Lessons

quiz vs the machine

Gold1500

Concurrency

The Double Checked Locking Bug

A clever lazy init that returns a half built object on the wrong memory model.

5 min read · core · beat Gold to climb

The intent

Double checked locking tries to make lazy initialization cheap: check whether the instance exists without a lock, and only take the lock if it appears null. The idea is to avoid the lock on the common path after the object is created.

Why it is broken

The naive version is unsafe because object construction is not atomic with the pointer assignment. A thread may publish a non null reference to an object whose fields are not yet visible to other threads. Two reorderings cause this:

  • The constructor writes can be reordered after the reference store.
  • Another core can read the reference but stale field values.

A second thread takes the fast path, sees a non null pointer, and uses a partially constructed object.

Correct versions

  • Mark the field volatile or use an acquire and release barrier so the publish is ordered after construction.
  • Prefer language idioms: a static holder class initialized by the class loader, or a thread safe lazy primitive.

Key idea

Double checked locking breaks because a reference can be published before the object is fully built. Use a volatile field or a holder idiom so construction happens before the read.

Check yourself

Answer to earn rating on the learn ladder.

1. Why is naive double checked locking unsafe?

2. What makes the pattern correct on a relaxed memory model?