Skip to main content

Threads & Happens-Before

intermediate13 min readLesson 94 of 180

start/join semantics, the run() vs start() trap, and the memory edge join() gives deterministic tests.

Threads, Runnables, and what the JVM promises

A Thread runs a Runnable concurrently; start() begins it, join() waits for completion:

Thread worker = new Thread(() -> System.out.println("work"));
worker.start();
worker.join();   // deterministic again — everything before join happened-before after

After join() returns, you may read everything the thread wrote — that is the happens-before edge you'll use in every deterministic exercise.

The classic beginner bug is calling run() instead of start(): that executes the Runnable on the current thread — sequential, no concurrency at all.

Threads are expensive (each carries ~1MB stack by default); that is why executors exist — Module-level coverage, Advanced goes deeper.