Java multithreading study notes - the life cycle of threads in Java

First, the state of the Java thread

        In Java, multithreading is driven by the core concept of Thread. During their lifetime, threads go through various states:

        The java.lang.Thread class contains a static State enumeration - it defines the state of the thread. It includes the following states:

        NEW - a newly created thread that has not yet started executing

        RUNNABLE – is running or ready to execute, but it is waiting for resource allocation

        BLOCKED – Waiting to acquire a monitor lock to enter or re-enter a synchronized block/method

        WAITING – waits for other threads to perform a specific action without any time limit

        TIMED_WAITING – Waits for some other thread to perform a specific action within a specified period of time

        TERMINATED – completed execution

1、NEW

        NEW Thread is a thread that has been created but not yet started. It stays that way until it is started with the start() method.

        The following code shows a newly created thread in the NEW state:

Runnable runnable = new NewState();
Thread t = new Thread(runnable);
System.out.println("Show:" + t.getState());

2、RUNNABLE

        When we create a new thread and call the start() method on it, it transitions from the NEW state to the RUNNABLE state. Threads in this state are either running or ready to run, but they are waiting for the system to allocate resources.

        In a multithreaded environment, the thread scheduler (which is part of the JVM) allocates a fixed amount of time to each thread. So it will run for a specific amount of time and then give control to other RUNNABLE threads.

        The code below will most likely output RUNNABLE, but there is no guarantee that it will still be in RUNNABLE state when t.getState() is executed. It may be scheduled by the Thread-Scheduler immediately and may complete execution. In this case we may get different output.

Runnable runnable = new NewState();
Thread t = new Thread(runnable);
t.start();
System.out.println("Show:" + t.getState());

3、BLOCKED

        When a thread is not currently eligible to run, it is in the BLOCKED state. It enters this state while waiting for the monitor to lock and trying to access a piece of code that is locked by another thread.

        Refer to the code below.

        (1) Two threads t1 and t2 are created.

        (2) t1 starts and enters the synchronized commonResource() method; this means that only one thread can access it; all other subsequent threads attempting to access this method will be blocked from further execution until the current thread finishes processing.

        (3) When t1 enters this method, it has been in an infinite while loop; this is just to simulate intensive computation so that all other threads cannot enter the method.

        (3) When we start t2 , it will try to enter the commonResource() method, which has been accessed by t1, therefore, t2 will remain in the  BLOCKED state.

public class BlockedState {
    public static void main(String[] args) throws InterruptedException {
        Thread t1 = new Thread(new DemoThreadB());
        Thread t2 = new Thread(new DemoThreadB());
        
        t1.start();
        t2.start();
        
        Thread.sleep(1000);
        
        Log.info(t2.getState());
        System.exit(0);
    }
}

class DemoThreadB implements Runnable {
    @Override
    public void run() {
        commonResource();
    }
    
    public static synchronized void commonResource() {
        while(true) {
            // Infinite loop to mimic heavy processing
            // 't1' won't leave this method
            // when 't2' try to enter this
        }
    }
}

4、WAITING

        A thread is in the WAITING state while waiting for other threads to perform a specific operation. According to the JavaDocs, any thread can enter this state by calling any of the following three methods:

        wait()、thread.join()、LockSupport.park()

        Refer to the following code.

        (1) Created and started t1

        (2) t1 creates a t2 and starts it

        (3) When t2 continues processing, we call t2.join(), which puts t1 in the WAITING state until t2 finishes executing

        (4) Since t1 is waiting for t2 to complete, we call t1.getState() from t2, and the state outputs WAITING

public class WaitingState implements Runnable {
    public static Thread t1;

    public static void main(String[] args) {
        t1 = new Thread(new WaitingState());
        t1.start();
    }

    public void run() {
        Thread t2 = new Thread(new DemoThreadWS());
        t2.start();

        try {
            t2.join();
        } catch (InterruptedException e) {
            Thread.currentThread().interrupt();
            Log.error("Thread interrupted", e);
        }
    }
}

class DemoThreadWS implements Runnable {
    public void run() {
        try {
            Thread.sleep(1000);
        } catch (InterruptedException e) {
            Thread.currentThread().interrupt();
            Log.error("Thread interrupted", e);
        }
        
        Log.info(WaitingState.t1.getState());
    }
}

5、TIMED_WAITING

        A thread is in the TIMED_WAITING state when it waits for another thread to perform a specific operation for a specified amount of time.

        According to the JavaDocs, there are five ways to put a thread in the TIMED_WAITING state:

        thread.sleep(long millis)
        wait(int timeout) or wait(int timeout, int nanos)
        thread.join(long millis)
        LockSupport.parkNanos
        LockSupport.parkUntil

        Referring to the following code, a thread t1 is created and started  , which goes to sleep with a timeout of 5 seconds; the output will be: TIMED_WAITING.

public class TimedWaitingState {
    public static void main(String[] args) throws InterruptedException {
        DemoThread obj1 = new DemoThread();
        Thread t1 = new Thread(obj1);
        t1.start();
        
        // The following sleep will give enough time for ThreadScheduler
        // to start processing of thread t1
        Thread.sleep(1000);
        Log.info(t1.getState());
    }
}

class DemoThread implements Runnable {
    @Override
    public void run() {
        try {
            Thread.sleep(5000);
        } catch (InterruptedException e) {
            Thread.currentThread().interrupt();
            Log.error("Thread interrupted", e);
        }
    }
}

6、TERMINATED

        This is the state of a dead thread. When it finishes executing or terminates abnormally, it is in the TERMINATED state.

        Referring to the following code, when we start thread t1 , the next statement Thread.sleep(1000) gives t1 enough time to complete, so this program gives us the following output: TERMINATED.

public class TerminatedState implements Runnable {
    public static void main(String[] args) throws InterruptedException {
        Thread t1 = new Thread(new TerminatedState());
        t1.start();
        // The following sleep method will give enough time for 
        // thread t1 to complete
        Thread.sleep(1000);
        Log.info(t1.getState());
    }
    
    @Override
    public void run() {
        // No processing in this block
    }
}

        In addition to the thread state, we can also use the isAlive() method to determine whether the thread is alive. For example, if we call the isAlive() method on this thread, it will also return false. In conclusion, a thread is alive if and only if it has been started and has not died.

Log.info(t1.isAlive());

2. Summary

        When programming in a multithreaded environment using Java threads, it is important to understand Java's thread cycles and thread states.

Guess you like

Origin blog.csdn.net/bashendixie5/article/details/123542178