Java > Concurrency and Multithreading > Thread Basics > Thread Lifecycle
Thread Lifecycle Demonstration
This example demonstrates the various stages of a Java thread's lifecycle, including NEW, RUNNABLE, BLOCKED, WAITING, TIMED_WAITING, and TERMINATED. Understanding these states is crucial for effective multithreaded programming and debugging.
Code Snippet: Thread Lifecycle States
This code creates a thread and explicitly demonstrates different states of the thread lifecycle.
NEW: The thread is created but not yet started.
RUNNABLE: The thread is executing in the Java virtual machine.
BLOCKED: The thread is blocked waiting for a monitor lock.
WAITING: The thread is waiting indefinitely for another thread to perform a particular action.
TIMED_WAITING: The thread is waiting for another thread to perform an action for up to a specified waiting time.
TERMINATED: The thread has exited.
public class ThreadLifecycle {
public static void main(String[] args) throws InterruptedException {
Thread thread = new Thread(() -> {
try {
System.out.println("Thread is running. State: " + Thread.currentThread().getState());
Thread.sleep(1000); // Simulate some work
synchronized (ThreadLifecycle.class) {
ThreadLifecycle.class.wait(); // Enter waiting state
}
System.out.println("Thread resumed. State: " + Thread.currentThread().getState());
} catch (InterruptedException e) {
System.out.println("Thread interrupted. State: " + Thread.currentThread().getState());
Thread.currentThread().interrupt();
}
System.out.println("Thread exiting. State: " + Thread.currentThread().getState());
});
System.out.println("Thread created. State: " + thread.getState());
thread.start();
System.out.println("Thread started. State: " + thread.getState());
Thread.sleep(200); //Give time to thread to start
System.out.println("Thread after short sleep. State: " + thread.getState());
Thread.sleep(2000); // Let thread enter waiting state
synchronized (ThreadLifecycle.class) {
ThreadLifecycle.class.notify(); // Resume thread from waiting state
}
thread.join(); // Wait for the thread to complete
System.out.println("Thread finished. State: " + thread.getState());
}
}
Concepts Behind the Snippet
A thread's lifecycle is governed by its state. Understanding these states is fundamental for debugging concurrency issues and ensuring correct program behavior. The `Thread.State` enum provides a way to check the current state of a thread. Common methods used to influence thread state include `start()`, `sleep()`, `wait()`, `notify()`, `notifyAll()`, `join()`, and `interrupt()`.
Real-Life Use Case
Consider a server application handling multiple client requests. Each request could be processed in a separate thread. Monitoring thread states helps identify bottlenecks. For example, a large number of threads in the BLOCKED state might indicate a contention issue for a shared resource. Identifying threads stuck in WAITING state could indicate a deadlock or logic error. Using proper thread management can improve response time and overall server performance.
Best Practices
Interview Tip
When discussing thread lifecycles in an interview, be prepared to explain each state and the transitions between them. Demonstrate your understanding of methods like `wait()`, `notify()`, and `join()` and how they affect thread state. Also, be ready to discuss common concurrency issues like deadlocks and race conditions and how to prevent them.
When to Use Them
Understanding thread states is essential when:
- Debugging concurrency issues (e.g., deadlocks, race conditions).
- Optimizing multithreaded applications for performance.
- Implementing custom concurrency constructs.
Memory Footprint
Each Java thread requires memory for its stack, local variables, and other thread-specific data. Excessive thread creation can lead to increased memory consumption and potentially impact performance. Thread pools are generally preferred over creating and destroying threads frequently to minimize overhead.
Alternatives
Alternatives to raw threads include:
Pros
Cons
FAQ
-
What is the difference between `wait()` and `sleep()`?
`wait()` releases the lock on the object, allowing other threads to acquire it, and puts the thread into the WAITING state until another thread calls `notify()` or `notifyAll()` on the same object. `sleep()` simply pauses the execution of the current thread for a specified duration, but it does not release any locks. -
What happens if I call `start()` on a thread more than once?
Calling `start()` on a thread more than once will throw an `IllegalThreadStateException`. Once a thread has been started, it cannot be started again. -
How do I stop a thread?
The preferred way to stop a thread is to use interruption. Set a flag that the thread checks periodically and exits gracefully when the flag is set, or use `Thread.interrupt()` to signal the thread to stop. Avoid using `Thread.stop()`, which is deprecated and unsafe.