Understanding the Java Thread Lifecycle with Code Examples

Répondu en utilisant GPT-4o-mini par Java Q&A Hub

Question :

Can you explain the Java thread lifecycle? Please be more detailed, preferably with source code level explanation

Réponse :

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:

  1. New: A thread that has been created but not yet started.
  2. Runnable: A thread that is ready to run and waiting for CPU time.
  3. Blocked: A thread that is blocked waiting for a monitor lock.
  4. Waiting: A thread that is waiting indefinitely for another thread to perform a particular action.
  5. Timed Waiting: A thread that is waiting for another thread to perform an action for up to a specified waiting time.
  6. Terminated: A thread that has completed its execution.

Thread Lifecycle States Explained with Code Examples

1. New State

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.");
    }
}

2. Runnable State

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
    }
}

3. Blocked 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
    }
}

4. Waiting State

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
        }
    }
}

5. Timed Waiting State

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
    }
}

6. Terminated State

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.");
    }
}

Summary of Thread States

  • New: Created but not started.
  • Runnable: Ready to run and waiting for CPU.
  • Blocked: Waiting for a lock.
  • Waiting: Waiting indefinitely for another thread.
  • Timed Waiting: Waiting for a specified time.
  • Terminated: Completed execution.

Understanding these states helps in managing thread behavior and ensuring proper synchronization in concurrent applications.