In Java's multithreaded world, understanding the lifecycle of a thread is fundamental for building reliable and high-performance applications. Each thread in Java transitions through several well-defined states, and knowing when and how these transitions occur is key to writing correct concurrent programs.
This guide walks you through the entire thread lifecycle, best practices, coordination techniques, and the evolving landscape with Java 8–21.
What is a Thread?
A thread is the smallest unit of execution within a Java program. Java supports multithreading via the Thread
class and Runnable
/Callable
interfaces, enabling developers to execute multiple parts of a program concurrently.
Thread Lifecycle: The 6 States
NEW → RUNNABLE → BLOCKED/WAITING/TIMED_WAITING → TERMINATED
1. NEW
- Thread is created but not started.
Thread t = new Thread(() -> {});
2. RUNNABLE
- Thread is ready to run and waiting for CPU time.
t.start();
3. BLOCKED
- Thread is waiting to acquire a lock.
4. WAITING
- Thread waits indefinitely for another thread to perform an action.
5. TIMED_WAITING
- Thread waits for a specific time using:
sleep(ms)
join(ms)
wait(ms)
6. TERMINATED
- Thread has completed execution or was aborted.
Lifecycle Transitions with Example
Thread t = new Thread(() -> {
try {
Thread.sleep(1000); // TIMED_WAITING
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
}
});
t.start(); // RUNNABLE
Coordination Tools in Lifecycle
wait()
,notify()
,notifyAll()
join()
to pause until another thread finishessleep()
to pause execution
Visibility and Memory
- Java Memory Model governs how threads see shared variables
volatile
ensures changes are visible across threadssynchronized
also flushes memory to maintain consistency
Synchronization & Locks
synchronized
blocksReentrantLock
,ReadWriteLock
,StampedLock
for advanced locking- Avoid nested locks to prevent deadlocks
java.util.concurrent Utilities
ExecutorService
manages thread poolsFuture
,CompletableFuture
handle asynchronous computationBlockingQueue
,ConcurrentHashMap
for thread-safe data structures
Real-World Applications
- Producer-Consumer: Uses
BlockingQueue
to share data between threads - File Processing: Thread pool handles large files in parallel
- Scheduling: Use
ScheduledExecutorService
for timed tasks
Thread Lifecycle and Java Versions
📌 What's New in Java Versions?
Java 8
- Lambdas simplify thread creation
CompletableFuture
for async programming
Java 9
- Flow API for reactive programming
Java 11+
- Enhancements to
CompletableFuture
Java 21
- Virtual Threads (Project Loom)
- Structured Concurrency
- Scoped Values for shared data management
Best Practices
- Always use
start()
notrun()
directly - Avoid long blocking in threads; use timeouts
- Use
ExecutorService
for pooling - Prefer higher-level abstractions like
CompletableFuture
Common Pitfalls
- Not handling
InterruptedException
- Race conditions on shared variables
- Holding locks for too long
- Deadlocks from improper lock ordering
Design Patterns Related to Lifecycle
- Worker Thread: Reuses threads to perform jobs
- Future Task: Asynchronous execution with result
- Thread-per-Message: New thread per client request
- Producer-Consumer: Coordination of job producers and consumers
Conclusion and Key Takeaways
- A thread in Java goes through six distinct states
- Knowing how and when these transitions happen prevents bugs
- Always use thread-safe communication and lock handling
- Adopt Java 21’s structured concurrency and virtual threads for modern scalability
FAQs
Q1: What is the difference between WAITING and TIMED_WAITING?
A: WAITING is indefinite; TIMED_WAITING waits with a timeout.
Q2: Can a thread go from BLOCKED to WAITING?
A: No, those are distinct paths; BLOCKED waits for a lock, WAITING for a condition.
Q3: What triggers the TERMINATED state?
A: The thread finishes execution or is terminated due to error.
Q4: How to debug a stuck thread?
A: Use jstack
or VisualVM to analyze thread dump.
Q5: Is calling run()
instead of start()
safe?
A: It’s not unsafe, but it won’t create a new thread—just runs in current one.
Q6: How to restart a thread?
A: You can’t restart a thread once terminated; create a new instance.
Q7: Why is volatile not enough for atomicity?
A: It guarantees visibility, not atomic operations.
Q8: Are virtual threads in Java 21 always in RUNNABLE state?
A: No, they follow the same states but are cheaper and more scalable.
Q9: What is a daemon thread?
A: Background thread that doesn’t prevent JVM from exiting.
Q10: Can thread states be monitored at runtime?
A: Yes, using Thread.getState()
or profiling tools.