What is safe publication, and what is the this-escape pro… — Cracked Java
// Concurrency & Multithreading · Thread-Safety Patterns
SeniorTheory

What is safe publication, and what is the this-escape problem?

Safe publication means making an object visible to other threads in such a way that they see it fully constructed — all its fields properly initialized — rather than a partially-built or stale version. Without it, a reader can observe a non-null reference whose fields still hold default values.

Why naive publication is broken

Object construction involves multiple writes (the reference assignment and each field write). The JMM permits these to be reordered and to be invisible to other threads without a happens-before edge. So a thread that reads a shared reference might see the reference but not the writes that initialized the object's fields:

class Holder { int n; Holder() { n = 42; } }
Holder shared; // plain field

// Thread A
shared = new Holder();   // reference write may become visible
                         // before the n = 42 write
// Thread B
if (shared != null) use(shared.n); // could legally read n == 0

The safe ways to publish

An object is safely published when both the publication and the construction are ordered by happens-before. The standard mechanisms:

  • Static initializer — fields/objects assigned in a static block or static field initializer are safely published by the JVM's class-initialization lock.
  • volatile field (or AtomicReference) — a volatile write happens-before the matching volatile read.
  • final field — final fields are frozen at the end of the constructor; any thread that reads the reference (published normally afterward) sees the correct final-field values. This is what makes immutable objects safe.
  • A lock — writing inside synchronized and reading inside synchronized on the same monitor.
  • A concurrent / synchronized collection — putting an object into a ConcurrentHashMap, BlockingQueue, etc. safely publishes it to whoever takes it out.

The this-escape problem

If this becomes visible to another thread before the constructor finishes, that thread can see a half-built object — and even final-field guarantees don't apply, because the freeze happens at the end of construction. Common ways this escapes:

class Listener {
    Listener(EventSource src) {
        // BAD: 'this' escapes before construction completes
        src.register(this);     // another thread may now call us
        this.handler = ...;     // ...before this runs
    }
}

Starting a thread from the constructor, registering a callback/listener, or passing this to any external code mid-construction all leak a not-yet-final object. The fix is a factory method: construct fully, then publish (e.g. register) afterward.

Mark your status