JUC (4): five/six states of shorthand threads

1. Five states

This is described from the operating system level

创建
调度
退出
时间到
事件等待
事件发生
新建
就绪
运行
终止
阻塞
  • [Creation Status] The thread object is only created at the language level, and has not yet been associated with the operating system thread
  • [Runnable state] (ready state) means that the thread has been created (associated with the operating system thread) and can be scheduled and executed by the CPU
  • [Running status] refers to the status of obtaining the running status of the CPU time slice
    • When the CPU time slice is used up, it will switch from [running state] to [runnable state], which will cause thread context switching
  • 【Blocking state】
    • If the blocking API is called, such as BIO reading and writing files, the thread will not actually use the CPU at this time, which will cause the thread context to switch and enter the [blocked state]
    • After the BIO operation is completed, the operating system will wake up the blocked thread and switch to the [runnable state]
    • The difference from [runnable state] is that for threads in [blocked state], as long as they do not wake up, the scheduler will never consider scheduling them
  • 【Termination state】Indicates that the thread has been executed, the life cycle has ended, and it will not be converted to other states

State transition conditions:

  • Ready state→Running state: After the process in the ready state is scheduled, it obtains processor resources (allocation of processor time slices), so the process changes from the ready state to the running state.
  • Running state → ready state: The process in the running state has to give up the processor after the time slice is used up, so that the process is converted from the running state to the ready state. Furthermore, in a preemptible operating system, when a higher priority process becomes ready, the scheduler transitions the executing process to the ready state, allowing the higher priority process to execute.
  • Running state → blocking state: When a process requests the use and allocation of a resource (such as a peripheral) or waits for an event to occur (such as the completion of an I/O operation), it transitions from the running state to the blocking state. The process requests the operating system to provide services in the form of system calls, which is a form of calling the operating system kernel process by running user mode programs.
  • Blocking state → ready state: When the process is waiting for an event to arrive, such as the end of the I/O operation or the end of the interrupt, the interrupt handler must change the state of the corresponding process from the blocked state to the ready state.

2. Six states

This is described from the Java API level

According to the Thread.State enumeration, it is divided into six states

insert image description here

insert image description here

  • The NEW thread has just been created, but the start() method has not been called yet
  • RUNNABLE After calling the start() method, note that the RUNNABLE state at the Java API level covers the [runnable state], [running state] and [blocked state] at the operating system level (thread blocking due to BIO, in Java Indistinguishable, still considered runnable)
  • BLOCKED , WAITING , TIMED_WAITING are all subdivisions of [blocking state] at the Java API level, which will be detailed in the state transition section later
  • TERMINATED when the thread code finishes running

Thread.State is an internal enumeration class that defines 6 enumeration constants:

public enum State {
    
    
    // 新建状态
    NEW,

    // 运行状态
    RUNNABLE,

    /**
     * 阻塞状态
     * Object.wait
     */
    BLOCKED,

    /**
     *  等待状态
     *  Object.wait
     *  Thread.join
     *  LockSupport.park
     */
    WAITING,

    /**
     *  限时等待状态
     *  Thread.sleep
     *  Object.wait
     *  Thread.join
     *  LockSupport.parkUntil
     *  LockSupport.parkNanos
     */
    TIMED_WAITING,

    // 终止状态
    TERMINATED;
}

Verify state in Java

@Slf4j(topic = "c.threadState")
public class ThreadState {
    
    
    public static void main(String[] args) throws IOException {
    
    
        Thread t1 = new Thread("t1") {
    
    
            @Override
            public void run() {
    
    
                log.debug("running...");
            }
        };

        Thread t2 = new Thread("t2") {
    
    
            @Override
            public void run() {
    
    
                while(true) {
    
     // runnable

                }
            }
        };
        t2.start();

        Thread t3 = new Thread("t3") {
    
    
            @Override
            public void run() {
    
    
                log.debug("running...");
            }
        };
        t3.start();

        Thread t4 = new Thread("t4") {
    
    
            @Override
            public void run() {
    
    
                synchronized (ThreadState.class) {
    
    
                    try {
    
    
                        Thread.sleep(1000000); // timed_waiting
                    } catch (InterruptedException e) {
    
    
                        e.printStackTrace();
                    }
                }
            }
        };
        t4.start();

        Thread t5 = new Thread("t5") {
    
    
            @Override
            public void run() {
    
    
                try {
    
    
                    t2.join(); // waiting
                } catch (InterruptedException e) {
    
    
                    e.printStackTrace();
                }
            }
        };
        t5.start();

        Thread t6 = new Thread("t6") {
    
    
            @Override
            public void run() {
    
    
                synchronized (ThreadState.class) {
    
     // blocked
                    try {
    
    
                        Thread.sleep(1000000);
                    } catch (InterruptedException e) {
    
    
                        e.printStackTrace();
                    }
                }
            }
        };
        t6.start();

        try {
    
    
            Thread.sleep(500);
        } catch (InterruptedException e) {
    
    
            e.printStackTrace();
        }
        log.debug("t1 state {}", t1.getState());
        log.debug("t2 state {}", t2.getState());
        log.debug("t3 state {}", t3.getState());
        log.debug("t4 state {}", t4.getState());
        log.debug("t5 state {}", t5.getState());
        log.debug("t6 state {}", t6.getState());
        System.in.read();
    }
}

output:

17:46:11.509 [t3] DEBUG c.threadState - running...
17:46:12.008 [main] DEBUG c.threadState - t1 state NEW
17:46:12.016 [main] DEBUG c.threadState - t2 state RUNNABLE
17:46:12.017 [main] DEBUG c.threadState - t3 state TERMINATED
17:46:12.017 [main] DEBUG c.threadState - t4 state TIMED_WAITING
17:46:12.017 [main] DEBUG c.threadState - t5 state WAITING
17:46:12.017 [main] DEBUG c.threadState - t6 state BLOCKED

Let’s analyze the transition of the six states of Java in different situations

Suppose there are threadsThread t

case 1NEW --> RUNNABLE
  • When calling t.start()the method , by NEW --> RUNNABLE
case 2RUNNABLE <--> WAITING

After the t threadsynchronized(obj) acquires the object lock with

  • obj.wait()When the method is called , the t thread starts fromRUNNABLE --> WAITING
  • call obj.notify(), obj.notifyAll()when t.interrupt()_
    • The contention lock is successful, and the t thread starts fromWAITING --> RUNNABLE
    • Contended lock failure, t thread fromWAITING --> BLOCKED
public class TestWaitNotify {
    
    
    final static Object obj = new Object();
    public static void main(String[] args) {
    
    
        new Thread(() -> {
    
    
            synchronized (obj) {
    
    
                log.debug("执行....");
                try {
    
    
                    obj.wait();
                } catch (InterruptedException e) {
    
    
                    e.printStackTrace();
                }
                log.debug("其它代码...."); // 断点
            }
        },"t1").start();
        new Thread(() -> {
    
    
            synchronized (obj) {
    
    
                log.debug("执行....");
                try {
    
    
                    obj.wait();
                } catch (InterruptedException e) {
    
    
                    e.printStackTrace();
                }
                log.debug("其它代码...."); // 断点
            }
        },"t2").start();

        TimeUnit.MILLISECONDS.sleep(500);
        log.debug("唤醒 obj 上其它线程");
        synchronized (obj) {
    
    
            obj.notifyAll(); // 唤醒obj上所有等待线程 断点
        }
    }
}
case 3RUNNABLE <--> WAITING
  • When the current thread calls t.join()the method , the current thread starts from RUNNABLE --> WAITINGNote that the current thread is waiting on the monitor of the t thread object
  • t When the thread finishes running, or calls interrupt() of the current thread , the current thread starts fromWAITING --> RUNNABLE
case 4RUNNABLE <--> WAITING
  • Calling LockSupport.park()the method the current thread will cause the current thread toRUNNABLE --> WAITING
  • Calling LockSupport.unpark(target thread) or calling thread interrupt()will make the target thread fromWAITING --> RUNNABLE
case 5RUNNABLE <--> TIMED_WAITING

After the t threadsynchronized(obj) acquires the object lock with

  • obj.wait(long n)When the method is called , the t thread starts fromRUNNABLE --> TIMED_WAITING
  • t thread waits for more than n milliseconds, or when calling obj.notify(), obj.notifyAll(),t.interrupt()
    • The contention lock is successful, and the t thread starts fromTIMED_WAITING --> RUNNABLE
    • Contended lock failure, t thread fromTIMED_WAITING --> BLOCKED
Situation 6RUNNABLE <--> TIMED_WAITING
  • When the current thread calls t.join(long n)the method , the current thread starts from RUNNABLE --> TIMED_WAITINGNote that the current thread is waiting on the monitor of the t thread object
  • When the current thread waits for more than n milliseconds, or when the t thread finishes running, or calls the current thread's , the current thread starts frominterrupt()TIMED_WAITING --> RUNNABLE
case 7RUNNABLE <--> TIMED_WAITING
  • Called by the current threadThread.sleep(long n) , the current thread starts fromRUNNABLE --> TIMED_WAITING
  • The current thread wait time exceeds n milliseconds, the current thread fromTIMED_WAITING --> RUNNABLE
case 8RUNNABLE <--> TIMED_WAITING
  • When the current thread calls LockSupport.parkNanos(long nanos)or LockSupport.parkUntil(long millis), the current thread starts fromRUNNABLE --> TIMED_WAITING
  • Calling LockSupport.unpark(target thread) or calling thread interrupt(), or waiting for timeout , will make the target thread fromTIMED_WAITING--> RUNNABLE
Situation 9RUNNABLE <--> BLOCKED
  • If the competition fails when the t threadsynchronized(obj) acquires the object lock withRUNNABLE --> BLOCKED
  • After the execution of the synchronization code block of the obj-locked thread is completed, BLOCKEDall re-compete. If thread t succeeds in the competition, BLOCKED --> RUNNABLEother failed threads will stillBLOCKED
Case 10RUNNABLE <--> TERMINATED
  • After all the codes of the current thread have finished running, enterTERMINATED

Guess you like

Origin blog.csdn.net/u013494827/article/details/126065555