Table of Contents
- Introduction to Thread Lifecycle
- Thread States Overview
- NEW State
- RUNNABLE State
- BLOCKED State
- WAITING State
- TIMED_WAITING State
- TERMINATED State
- State Transitions
- Monitoring Thread States
- Best Practices
- Complete Examples
Introduction to Thread Lifecycle
In Java, every thread has a lifecycle that consists of various states. Understanding these states is crucial for effective multithreaded programming. The thread states are defined in the Thread.State enum.
Thread States Overview
Java threads can be in one of these six states:
- NEW - Thread created but not started
- RUNNABLE - Thread is executing or ready to execute
- BLOCKED - Thread waiting for a monitor lock
- WAITING - Thread waiting indefinitely for another thread
- TIMED_WAITING - Thread waiting for a specified time
- TERMINATED - Thread has finished execution
Thread State Diagram:
NEW → RUNNABLE → BLOCKED → WAITING → TIMED_WAITING → TERMINATED
NEW State
A thread is in the NEW state when it's created but not yet started.
Characteristics:
- Thread object is created
start()method not called yet- No system resources allocated for execution
Example:
public class NewStateExample {
public static void main(String[] args) {
// Create a thread but don't start it
Thread thread = new Thread(() -> {
System.out.println("Thread is running");
});
// Check thread state - should be NEW
System.out.println("Thread state: " + thread.getState()); // NEW
System.out.println("Is alive: " + thread.isAlive()); // false
// Thread remains in NEW state until start() is called
}
}
Output:
Thread state: NEW Is alive: false
RUNNABLE State
A thread enters the RUNNABLE state when start() is called. It may be executing or ready to execute.
Characteristics:
- Thread is eligible to run
- May be waiting for CPU time
- Can transition to other states from here
Example:
public class RunnableStateExample {
public static void main(String[] args) {
Thread thread = new Thread(() -> {
// Simulate some work
for (int i = 0; i < 5; i++) {
System.out.println("Working... " + i);
try {
Thread.sleep(100);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
});
System.out.println("Before start: " + thread.getState()); // NEW
thread.start();
System.out.println("After start: " + thread.getState()); // RUNNABLE
// Wait for thread to complete
try {
thread.join();
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("After completion: " + thread.getState()); // TERMINATED
}
}
Output:
Before start: NEW After start: RUNNABLE Working... 0 Working... 1 Working... 2 Working... 3 Working... 4 After completion: TERMINATED
BLOCKED State
A thread enters BLOCKED state when it's waiting to acquire a monitor lock.
Common scenarios:
- Waiting to enter synchronized block/method
- Waiting to re-enter synchronized block after calling
wait()
Example:
public class BlockedStateExample {
private static final Object lock = new Object();
public static void main(String[] args) throws InterruptedException {
Thread thread1 = new Thread(() -> {
synchronized (lock) {
System.out.println("Thread 1 acquired lock");
try {
// Hold lock for 2 seconds
Thread.sleep(2000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("Thread 1 releasing lock");
}
});
Thread thread2 = new Thread(() -> {
// This thread will be BLOCKED until thread1 releases the lock
synchronized (lock) {
System.out.println("Thread 2 acquired lock");
}
});
thread1.start();
Thread.sleep(100); // Ensure thread1 starts first
thread2.start();
Thread.sleep(100); // Ensure thread2 tries to acquire lock
// Check thread2 state - should be BLOCKED
System.out.println("Thread 2 state: " + thread2.getState()); // BLOCKED
thread1.join();
thread2.join();
}
}
Output:
Thread 1 acquired lock Thread 2 state: BLOCKED Thread 1 releasing lock Thread 2 acquired lock
WAITING State
A thread enters WAITING state when it waits indefinitely for another thread.
Methods that cause WAITING state:
object.wait()- without timeoutthread.join()- without timeoutLockSupport.park()
Example:
public class WaitingStateExample {
private static final Object lock = new Object();
public static void main(String[] args) throws InterruptedException {
Thread waitingThread = new Thread(() -> {
synchronized (lock) {
try {
System.out.println("Thread is going to wait...");
lock.wait(); // Enters WAITING state
System.out.println("Thread woke up!");
} catch (InterruptedException e) {
e.printStackTrace();
}
}
});
waitingThread.start();
Thread.sleep(100); // Ensure thread enters wait state
// Check state - should be WAITING
System.out.println("Thread state: " + waitingThread.getState()); // WAITING
// Notify the waiting thread after 2 seconds
Thread notifier = new Thread(() -> {
try {
Thread.sleep(2000);
synchronized (lock) {
lock.notify();
System.out.println("Notified waiting thread");
}
} catch (InterruptedException e) {
e.printStackTrace();
}
});
notifier.start();
waitingThread.join();
notifier.join();
}
}
Output:
Thread is going to wait... Thread state: WAITING Notified waiting thread Thread woke up!
TIMED_WAITING State
A thread enters TIMED_WAITING state when it waits for a specified time period.
Methods that cause TIMED_WAITING state:
Thread.sleep(millis)object.wait(timeout)thread.join(timeout)LockSupport.parkNanos()LockSupport.parkUntil()
Example:
public class TimedWaitingStateExample {
public static void main(String[] args) throws InterruptedException {
Thread thread = new Thread(() -> {
try {
System.out.println("Thread going to sleep for 3 seconds...");
Thread.sleep(3000); // Enters TIMED_WAITING state
System.out.println("Thread woke up!");
} catch (InterruptedException e) {
e.printStackTrace();
}
});
thread.start();
Thread.sleep(100); // Ensure thread enters sleep
// Check state - should be TIMED_WAITING
System.out.println("Thread state: " + thread.getState()); // TIMED_WAITING
thread.join();
System.out.println("Final state: " + thread.getState()); // TERMINATED
}
}
Output:
Thread going to sleep for 3 seconds... Thread state: TIMED_WAITING Thread woke up! Final state: TERMINATED
TERMINATED State
A thread enters TERMINATED state when it has finished execution.
Characteristics:
run()method has completed- Thread cannot be restarted
- System resources are released
Example:
public class TerminatedStateExample {
public static void main(String[] args) throws InterruptedException {
Thread thread = new Thread(() -> {
System.out.println("Thread is running");
// Thread will terminate after run() completes
});
System.out.println("Before start: " + thread.getState()); // NEW
thread.start();
Thread.sleep(100); // Ensure thread completes
System.out.println("After completion: " + thread.getState()); // TERMINATED
System.out.println("Is alive: " + thread.isAlive()); // false
// Trying to restart a terminated thread
try {
thread.start(); // This will throw IllegalThreadStateException
} catch (IllegalThreadStateException e) {
System.out.println("Cannot restart terminated thread: " + e.getMessage());
}
}
}
Output:
Before start: NEW Thread is running After completion: TERMINATED Is alive: false Cannot restart terminated thread: null
State Transitions
Complete State Transition Example:
public class ThreadStateTransitions {
private static final Object lock = new Object();
private static boolean condition = false;
public static void main(String[] args) throws InterruptedException {
Thread thread = new Thread(() -> {
System.out.println("1. Thread started - State: " + Thread.currentThread().getState());
// Transition to TIMED_WAITING
try {
System.out.println("2. Going to sleep - Transition to TIMED_WAITING");
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
// Transition to BLOCKED
synchronized (lock) {
System.out.println("3. Acquired lock - Doing work");
try {
Thread.sleep(500);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
// Transition to WAITING
synchronized (lock) {
try {
System.out.println("4. Going to wait - Transition to WAITING");
while (!condition) {
lock.wait();
}
System.out.println("5. Condition met - Continuing execution");
} catch (InterruptedException e) {
e.printStackTrace();
}
}
System.out.println("6. Thread completing - Transition to TERMINATED");
});
// Monitor thread states
Thread monitor = new Thread(() -> {
while (thread.isAlive()) {
Thread.State state = thread.getState();
System.out.println("Monitor - Thread state: " + state);
try {
Thread.sleep(200);
} catch (InterruptedException e) {
break;
}
}
});
System.out.println("Initial state: " + thread.getState()); // NEW
thread.start();
monitor.start();
// Let thread sleep complete
Thread.sleep(1200);
// Let thread acquire lock and release it
Thread.sleep(800);
// Notify waiting thread after 2 seconds
Thread.sleep(2000);
synchronized (lock) {
condition = true;
lock.notify();
System.out.println("Main thread notified waiting thread");
}
thread.join();
monitor.interrupt();
monitor.join();
System.out.println("Final state: " + thread.getState()); // TERMINATED
}
}
Output:
Initial state: NEW 1. Thread started - State: RUNNABLE 2. Going to sleep - Transition to TIMED_WAITING Monitor - Thread state: TIMED_WAITING Monitor - Thread state: TIMED_WAITING Monitor - Thread state: TIMED_WAITING Monitor - Thread state: TIMED_WAITING Monitor - Thread state: TIMED_WAITING Monitor - Thread state: RUNNABLE 3. Acquired lock - Doing work Monitor - Thread state: RUNNABLE Monitor - Thread state: RUNNABLE Monitor - Thread state: RUNNABLE 4. Going to wait - Transition to WAITING Monitor - Thread state: WAITING Monitor - Thread state: WAITING Monitor - Thread state: WAITING Monitor - Thread state: WAITING Monitor - Thread state: WAITING Main thread notified waiting thread 5. Condition met - Continuing execution 6. Thread completing - Transition to TERMINATED Monitor - Thread state: TERMINATED Final state: TERMINATED
Monitoring Thread States
Advanced Thread Monitoring Example:
import java.util.*;
import java.util.concurrent.*;
public class ThreadMonitor {
private static final Map<String, Thread> threads = new ConcurrentHashMap<>();
private static volatile boolean monitoring = true;
public static void main(String[] args) throws InterruptedException {
// Create various threads in different states
createBlockedThreads();
createWaitingThreads();
createTimedWaitingThreads();
createRunningThreads();
// Start monitoring
Thread monitorThread = new Thread(() -> {
while (monitoring) {
System.out.println("\n=== Thread States Snapshot ===");
System.out.printf("%-20s %-15s %-10s%n", "Thread Name", "State", "Is Alive");
System.out.println("-----------------------------------------------");
threads.forEach((name, thread) -> {
if (thread != null) {
System.out.printf("%-20s %-15s %-10s%n",
name, thread.getState(), thread.isAlive());
}
});
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
break;
}
}
});
monitorThread.start();
// Let monitoring run for 10 seconds
Thread.sleep(10000);
monitoring = false;
monitorThread.interrupt();
// Cleanup
threads.values().forEach(Thread::interrupt);
threads.clear();
}
private static void createBlockedThreads() {
Object lock = new Object();
Thread holder = new Thread(() -> {
synchronized (lock) {
try {
Thread.sleep(5000); // Hold lock for 5 seconds
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
}
}
});
holder.setName("Lock-Holder");
threads.put("Lock-Holder", holder);
holder.start();
// Create threads that will be blocked
for (int i = 0; i < 2; i++) {
Thread blocked = new Thread(() -> {
synchronized (lock) {
System.out.println(Thread.currentThread().getName() + " acquired lock");
}
});
blocked.setName("Blocked-" + i);
threads.put("Blocked-" + i, blocked);
blocked.start();
}
}
private static void createWaitingThreads() {
Object waitObject = new Object();
Thread waiter = new Thread(() -> {
synchronized (waitObject) {
try {
waitObject.wait(); // Wait indefinitely
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
}
}
});
waiter.setName("Waiter");
threads.put("Waiter", waiter);
waiter.start();
}
private static void createTimedWaitingThreads() {
for (int i = 0; i < 2; i++) {
Thread sleeper = new Thread(() -> {
try {
Thread.sleep(10000); // Sleep for 10 seconds
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
}
});
sleeper.setName("Sleeper-" + i);
threads.put("Sleeper-" + i, sleeper);
sleeper.start();
}
}
private static void createRunningThreads() {
for (int i = 0; i < 2; i++) {
Thread runner = new Thread(() -> {
long count = 0;
while (!Thread.currentThread().isInterrupted()) {
count++;
if (count % 100000000 == 0) {
System.out.println(Thread.currentThread().getName() + " is running...");
}
}
});
runner.setName("Runner-" + i);
threads.put("Runner-" + i, runner);
runner.start();
}
}
}
Best Practices
1. Proper State Management:
public class ProperThreadManagement {
private volatile boolean running = true;
public void startWorker() {
Thread worker = new Thread(() -> {
while (running && !Thread.currentThread().isInterrupted()) {
try {
// Do work
performTask();
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
break;
}
}
System.out.println("Worker thread terminated gracefully");
});
worker.start();
}
public void stopWorker() {
running = false;
}
private void performTask() throws InterruptedException {
// Simulate work
Thread.sleep(1000);
System.out.println("Task performed by: " + Thread.currentThread().getName());
}
public static void main(String[] args) throws InterruptedException {
ProperThreadManagement manager = new ProperThreadManagement();
manager.startWorker();
Thread.sleep(5000);
manager.stopWorker();
}
}
2. Avoiding Deadlocks:
public class DeadlockPrevention {
private final Object lock1 = new Object();
private final Object lock2 = new Object();
public void method1() {
synchronized (lock1) {
System.out.println(Thread.currentThread().getName() + " acquired lock1");
try { Thread.sleep(100); } catch (InterruptedException e) {}
synchronized (lock2) {
System.out.println(Thread.currentThread().getName() + " acquired lock2");
}
}
}
public void method2() {
// Acquire locks in the same order to prevent deadlock
synchronized (lock1) {
System.out.println(Thread.currentThread().getName() + " acquired lock1");
try { Thread.sleep(100); } catch (InterruptedException e) {}
synchronized (lock2) {
System.out.println(Thread.currentThread().getName() + " acquired lock2");
}
}
}
public static void main(String[] args) {
DeadlockPrevention example = new DeadlockPrevention();
Thread t1 = new Thread(() -> {
for (int i = 0; i < 5; i++) {
example.method1();
}
});
Thread t2 = new Thread(() -> {
for (int i = 0; i < 5; i++) {
example.method2();
}
});
t1.start();
t2.start();
try {
t1.join();
t2.join();
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("Both threads completed successfully");
}
}
3. Using Timeouts for Waiting:
public class TimeoutWaitingExample {
private final Object lock = new Object();
private boolean condition = false;
public void waitWithTimeout(long timeoutMs) throws InterruptedException {
synchronized (lock) {
long startTime = System.currentTimeMillis();
long remaining = timeoutMs;
while (!condition && remaining > 0) {
lock.wait(remaining);
remaining = timeoutMs - (System.currentTimeMillis() - startTime);
}
if (condition) {
System.out.println("Condition met within timeout");
} else {
System.out.println("Timeout reached, condition not met");
}
}
}
public void setCondition() {
synchronized (lock) {
condition = true;
lock.notifyAll();
}
}
public static void main(String[] args) throws InterruptedException {
TimeoutWaitingExample example = new TimeoutWaitingExample();
Thread waiter = new Thread(() -> {
try {
System.out.println("Waiting for condition with 3 second timeout...");
example.waitWithTimeout(3000);
} catch (InterruptedException e) {
e.printStackTrace();
}
});
waiter.start();
// Don't set condition - let timeout occur
Thread.sleep(4000);
// Start another waiter and set condition quickly
Thread waiter2 = new Thread(() -> {
try {
System.out.println("Waiting for condition with 5 second timeout...");
example.waitWithTimeout(5000);
} catch (InterruptedException e) {
e.printStackTrace();
}
});
waiter2.start();
Thread.sleep(100);
example.setCondition();
waiter.join();
waiter2.join();
}
}
Complete Examples
Complete Thread Lifecycle Demonstration:
import java.util.*;
import java.util.concurrent.locks.*;
public class CompleteThreadLifecycleDemo {
private static final Object syncLock = new Object();
private static final ReentrantLock reentrantLock = new ReentrantLock();
private static final Condition condition = reentrantLock.newCondition();
public static void main(String[] args) throws InterruptedException {
System.out.println("=== Complete Thread Lifecycle Demonstration ===\n");
// 1. NEW State Demo
demoNewState();
// 2. RUNNABLE State Demo
demoRunnableState();
// 3. BLOCKED State Demo
demoBlockedState();
// 4. WAITING State Demo
demoWaitingState();
// 5. TIMED_WAITING State Demo
demoTimedWaitingState();
// 6. TERMINATED State Demo
demoTerminatedState();
// 7. Complex State Transitions
demoComplexTransitions();
System.out.println("\n=== Demonstration Complete ===");
}
private static void demoNewState() {
System.out.println("1. NEW State Demonstration:");
Thread thread = new Thread(() -> {
System.out.println("This will never print - thread not started");
});
System.out.println("Thread state: " + thread.getState());
System.out.println("Is alive: " + thread.isAlive());
System.out.println();
}
private static void demoRunnableState() throws InterruptedException {
System.out.println("2. RUNNABLE State Demonstration:");
Thread thread = new Thread(() -> {
System.out.println("Thread is in RUNNABLE state and executing");
// Busy work to keep thread RUNNABLE
long count = 0;
for (int i = 0; i < 1000000; i++) {
count += i;
}
});
System.out.println("Before start: " + thread.getState());
thread.start();
Thread.sleep(10); // Give thread time to start
System.out.println("After start: " + thread.getState());
thread.join();
System.out.println();
}
private static void demoBlockedState() throws InterruptedException {
System.out.println("3. BLOCKED State Demonstration:");
Thread lockHolder = new Thread(() -> {
synchronized (syncLock) {
System.out.println("Lock holder acquired lock");
try {
Thread.sleep(2000); // Hold lock
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("Lock holder releasing lock");
}
});
Thread blockedThread = new Thread(() -> {
System.out.println("Blocked thread trying to acquire lock...");
synchronized (syncLock) {
System.out.println("Blocked thread acquired lock");
}
});
lockHolder.start();
Thread.sleep(100); // Ensure lockHolder gets lock first
blockedThread.start();
Thread.sleep(100); // Ensure blockedThread tries to acquire lock
System.out.println("Blocked thread state: " + blockedThread.getState());
lockHolder.join();
blockedThread.join();
System.out.println();
}
private static void demoWaitingState() throws InterruptedException {
System.out.println("4. WAITING State Demonstration:");
Thread waitingThread = new Thread(() -> {
synchronized (syncLock) {
try {
System.out.println("Thread entering WAITING state");
syncLock.wait(); // Wait indefinitely
System.out.println("Thread resumed from WAITING state");
} catch (InterruptedException e) {
e.printStackTrace();
}
}
});
waitingThread.start();
Thread.sleep(100); // Ensure thread enters wait
System.out.println("Waiting thread state: " + waitingThread.getState());
// Resume the thread after 1 second
Thread.sleep(1000);
synchronized (syncLock) {
syncLock.notify();
}
waitingThread.join();
System.out.println();
}
private static void demoTimedWaitingState() throws InterruptedException {
System.out.println("5. TIMED_WAITING State Demonstration:");
Thread sleepingThread = new Thread(() -> {
try {
System.out.println("Thread entering TIMED_WAITING state");
Thread.sleep(2000); // Sleep for 2 seconds
System.out.println("Thread woke up from TIMED_WAITING");
} catch (InterruptedException e) {
e.printStackTrace();
}
});
sleepingThread.start();
Thread.sleep(100); // Ensure thread enters sleep
System.out.println("Sleeping thread state: " + sleepingThread.getState());
sleepingThread.join();
System.out.println();
}
private static void demoTerminatedState() throws InterruptedException {
System.out.println("6. TERMINATED State Demonstration:");
Thread shortLivedThread = new Thread(() -> {
System.out.println("Thread executing briefly");
});
System.out.println("Before start: " + shortLivedThread.getState());
shortLivedThread.start();
Thread.sleep(100); // Ensure thread completes
System.out.println("After completion: " + shortLivedThread.getState());
System.out.println("Is alive: " + shortLivedThread.isAlive());
System.out.println();
}
private static void demoComplexTransitions() throws InterruptedException {
System.out.println("7. Complex State Transitions Demonstration:");
List<Thread> threads = new ArrayList<>();
List<String> stateLog = Collections.synchronizedList(new ArrayList<>());
// Create threads with different behaviors
for (int i = 0; i < 3; i++) {
final int threadId = i;
Thread thread = new Thread(() -> {
logState(stateLog, "Thread-" + threadId + " started", Thread.currentThread().getState());
// TIMED_WAITING
try {
Thread.sleep(1000 + threadId * 500);
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
}
// BLOCKED (try to acquire lock)
synchronized (syncLock) {
logState(stateLog, "Thread-" + threadId + " acquired lock", Thread.currentThread().getState());
try {
Thread.sleep(500);
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
}
}
// WAITING with ReentrantLock
reentrantLock.lock();
try {
logState(stateLog, "Thread-" + threadId + " waiting on condition", Thread.currentThread().getState());
condition.await(); // WAITING
logState(stateLog, "Thread-" + threadId + " condition satisfied", Thread.currentThread().getState());
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
} finally {
reentrantLock.unlock();
}
logState(stateLog, "Thread-" + threadId + " completed", Thread.currentThread().getState());
});
threads.add(thread);
}
// Start all threads
for (Thread thread : threads) {
thread.start();
}
// Monitor states for 3 seconds
Thread monitor = new Thread(() -> {
long startTime = System.currentTimeMillis();
while (System.currentTimeMillis() - startTime < 3000) {
for (int i = 0; i < threads.size(); i++) {
Thread thread = threads.get(i);
logState(stateLog, "Monitor - Thread-" + i, thread.getState());
}
try {
Thread.sleep(200);
} catch (InterruptedException e) {
break;
}
}
});
monitor.start();
Thread.sleep(2500);
// Signal all waiting threads
reentrantLock.lock();
try {
condition.signalAll();
} finally {
reentrantLock.unlock();
}
// Wait for all threads to complete
for (Thread thread : threads) {
thread.join();
}
monitor.join();
// Print state log
System.out.println("\nState Transition Log:");
System.out.println("=====================");
stateLog.forEach(System.out::println);
}
private static void logState(List<String> log, String threadName, Thread.State state) {
String entry = String.format("%-30s %-15s", threadName, state);
log.add(entry);
}
}
Expected Output:
=== Complete Thread Lifecycle Demonstration === 1. NEW State Demonstration: Thread state: NEW Is alive: false 2. RUNNABLE State Demonstration: Before start: NEW Thread is in RUNNABLE state and executing After start: RUNNABLE 3. BLOCKED State Demonstration: Lock holder acquired lock Blocked thread trying to acquire lock... Blocked thread state: BLOCKED Lock holder releasing lock Blocked thread acquired lock 4. WAITING State Demonstration: Thread entering WAITING state Waiting thread state: WAITING Thread resumed from WAITING state 5. TIMED_WAITING State Demonstration: Thread entering TIMED_WAITING state Sleeping thread state: TIMED_WAITING Thread woke up from TIMED_WAITING 6. TERMINATED State Demonstration: Before start: NEW Thread executing briefly After completion: TERMINATED Is alive: false 7. Complex State Transitions Demonstration: State Transition Log: ===================== Thread-0 started RUNNABLE Monitor - Thread-0 TIMED_WAITING Monitor - Thread-1 TIMED_WAITING Monitor - Thread-2 TIMED_WAITING Thread-0 acquired lock RUNNABLE Thread-0 waiting on condition WAITING Thread-1 acquired lock RUNNABLE Thread-1 waiting on condition WAITING Thread-2 acquired lock RUNNABLE Thread-2 waiting on condition WAITING Thread-0 condition satisfied RUNNABLE Thread-0 completed RUNNABLE Thread-1 condition satisfied RUNNABLE Thread-1 completed RUNNABLE Thread-2 condition satisfied RUNNABLE Thread-2 completed RUNNABLE
Key Takeaways
- NEW: Thread created but not started
- RUNNABLE: Thread is executing or ready to execute
- BLOCKED: Waiting for monitor lock
- WAITING: Waiting indefinitely for another thread
- TIMED_WAITING: Waiting for a specified time period
- TERMINATED: Thread has completed execution
Important Points:
- Use
Thread.getState()to check thread state - Thread states help in debugging multithreading issues
- Proper state management prevents deadlocks and resource leaks
- Always handle thread interruption properly
- Use timeouts for waiting operations to avoid indefinite blocking
Understanding thread lifecycle states is essential for writing robust, efficient, and deadlock-free multithreaded applications in Java.