Thread Foundations and Lifecycle Mechanics
Threads are the smallest units of execution in concurrent programming. Before diving into locks and high-level utilities, one must fundamentally understand the thread itself: how it is created, scheduled, and how its states transition under the JVM's hood.
1. Defining Tasks vs. Creating Threads
While there are multiple ways to define a task, there is essentially only one way to create a thread in Java: new Thread().start().
1.1 Runnable vs. Callable
- Runnable: Defines a task with no return value (
void) and no checked exceptions. - Callable: Returns a generic result
Vand can throw checked exceptions. - FutureTask: A bridge that wraps a
Callable, implementsRunnable, and stores the result for later retrieval viaget().
1.2 The "Start0" Reality
Calling run() is just a normal method call in the current thread. Only start() triggers the JVM's native start0() method, which calls the OS-specific API (like pthread_create on Linux) to allocate a new kernel thread and its 1MB stack.
2. The 6 States of a Java Thread
The Thread.State enum defines a thread's lifecycle in the eyes of the JVM:
- NEW: Object created, but
start()not yet called. - RUNNABLE: Executing or waiting for a CPU time slice. (Java groups "Ready" and "Running" into one state).
- BLOCKED: Waiting specifically for a
synchronizedlock. - WAITING: Infinite wait for another thread (via
wait(),join(), orLockSupport.park()). - TIMED_WAITING: Wait with a timeout (via
sleep(ms),wait(ms), orparkNanos()). - TERMINATED: Execution finished or crashed.
State Transition Matrix
| Transition | Causality | State |
|---|---|---|
| RUNNABLE → BLOCKED | Attempting to enter a locked synchronized block. |
BLOCKED |
| RUNNABLE → WAITING | object.wait() or LockSupport.park(). |
WAITING |
| WAITING → RUNNABLE | object.notify() or LockSupport.unpark(). |
RUNNABLE |
| RUNNABLE → TIMED_WAITING | Thread.sleep(ms). |
TIMED_WAITING |
3. High-Frequency Mechanics: sleep() vs. wait()
This is a common architectural comparison, but the logic is structural:
Thread.sleep(ms): A static method. The thread sleeps but keeps all its locks. It is a "pause" in execution.Object.wait(): An instance method. The thread releases the object's lock and joins the wait-set.- The
synchronizedRequirement:wait()must be called inside asynchronizedblock for that object. This ensures the condition check and the "release-and-wait" action is atomic, preventing Lost Wakeups.
4. The Collaborative Interrupt
Java deprecated Thread.stop() because it was unsafe—it killed threads instantly, potentially leaving shared data in an inconsistent state (e.g., mid-transaction).
The modern solution is Interruption:
- Signal:
thread.interrupt()sets an internal flag. - Response: The thread checks
Thread.currentThread().isInterrupted()and shuts down gracefully. - Exception: If a thread is blocked in
sleep()orwait(), it will immediately wake up and throw anInterruptedException, giving it a chance to clean up resources before exiting.
5. Daemon Threads: The Background Guards
A thread can be marked as a Daemon (setDaemon(true)).
- JVM behavior: The JVM will exit automatically once all non-daemon threads (user threads) have finished, even if daemon threads are still running.
- Common examples: Garbage Collector (GC), JIT compiler, or heartbeat monitors.