Can you explain the Java thread lifecycle? Please be more detailed, preferably with source code level explanation
Certainly! The Java thread lifecycle consists of several states that a thread can be in during its execution. Understanding these states is crucial for effective multithreading in Java. The main states in the Java thread lifecycle are:
When a thread is created, it is in the New state. This is done by instantiating a Thread
object.
public class ThreadLifecycleExample {
public static void main(String[] args) {
Thread thread = new Thread(new MyRunnable());
// The thread is in the NEW state here
}
}
class MyRunnable implements Runnable {
@Override
public void run() {
System.out.println("Thread is running.");
}
}
A thread enters the Runnable state when the start()
method is called. It is now eligible to run but may not be running immediately due to CPU scheduling.
public class ThreadLifecycleExample {
public static void main(String[] args) {
Thread thread = new Thread(new MyRunnable());
thread.start(); // The thread is now in the RUNNABLE state
}
}
A thread enters the Blocked state when it tries to acquire a lock that another thread holds. Here’s an example:
class SharedResource {
synchronized void synchronizedMethod() {
System.out.println(Thread.currentThread().getName() + " is in synchronized method.");
try {
Thread.sleep(1000); // Simulate some work
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
public class ThreadLifecycleExample {
public static void main(String[] args) {
SharedResource resource = new SharedResource();
Thread thread1 = new Thread(() -> resource.synchronizedMethod());
Thread thread2 = new Thread(() -> resource.synchronizedMethod());
thread1.start();
thread2.start(); // thread2 will be BLOCKED until thread1 releases the lock
}
}
A thread enters the Waiting state when it calls wait()
, join()
, or LockSupport.park()
. It will remain in this state until another thread signals it to wake up.
class WaitingThread implements Runnable {
public void run() {
synchronized (this) {
try {
System.out.println(Thread.currentThread().getName() + " is waiting.");
wait(); // Thread goes into WAITING state
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
public class ThreadLifecycleExample {
public static void main(String[] args) throws InterruptedException {
WaitingThread waitingThread = new WaitingThread();
Thread thread = new Thread(waitingThread);
thread.start();
Thread.sleep(1000); // Simulate some work
synchronized (waitingThread) {
waitingThread.notify(); // Wakes up the waiting thread
}
}
}
A thread enters the Timed Waiting state when it calls methods like sleep(milliseconds)
, wait(milliseconds)
, or join(milliseconds)
.
public class ThreadLifecycleExample {
public static void main(String[] args) throws InterruptedException {
Thread thread = new Thread(() -> {
try {
System.out.println(Thread.currentThread().getName() + " is sleeping.");
Thread.sleep(2000); // Thread goes into TIMED_WAITING state
} catch (InterruptedException e) {
e.printStackTrace();
}
});
thread.start();
thread.join(); // Main thread waits for the thread to finish
}
}
A thread enters the Terminated state when it has completed its execution, either normally or due to an exception.
public class ThreadLifecycleExample {
public static void main(String[] args) {
Thread thread = new Thread(() -> {
System.out.println(Thread.currentThread().getName() + " is running.");
});
thread.start();
try {
thread.join(); // Wait for the thread to finish
} catch (InterruptedException e) {
e.printStackTrace();
}
// At this point, the thread is in the TERMINATED state
System.out.println("Thread has finished execution.");
}
}
Understanding these states helps in managing thread behavior and ensuring proper synchronization in concurrent applications.