线程的状态

作者: 我可能是个假开发 | 来源:发表于2023-11-29 11:30 被阅读0次

    一、操作系统层面的五种状态

    image.png
    • 初始状态:仅是在语言层面创建了线程对象,还未与操作系统线程关联
    • 可运行状态(就绪状态):指该线程已经被创建(与操作系统线程关联),可以由 CPU 调度执行
    • 运行状态:指获取了 CPU 时间片运行中的状态
      • 当 CPU 时间片用完,会从运行状态转换至可运行状态,会导致线程的上下文切换
    • 阻塞状态
      • 如果调用了阻塞 API,如 BIO 读写文件,这时该线程实际不会用到 CPU,会导致线程上下文切换,进入阻塞状态
      • 等 BIO 操作完毕,会由操作系统唤醒阻塞的线程,转换至可运行状态
      • 可运行状态的区别是,对阻塞状态的线程来说只要它们一直不唤醒,调度器就一直不会考虑调度它们
    • 终止状态:表示线程已经执行完毕,生命周期已经结束,不会再转换为其它状态

    二、 Java API 层面的六种状态

    public enum State {
            /**
             * Thread state for a thread which has not yet started.
             */
            NEW,
    
            /**
             * Thread state for a runnable thread.  A thread in the runnable
             * state is executing in the Java virtual machine but it may
             * be waiting for other resources from the operating system
             * such as processor.
             */
            RUNNABLE,
    
            /**
             * Thread state for a thread blocked waiting for a monitor lock.
             * A thread in the blocked state is waiting for a monitor lock
             * to enter a synchronized block/method or
             * reenter a synchronized block/method after calling
             * {@link Object#wait() Object.wait}.
             */
            BLOCKED,
    
            /**
             * Thread state for a waiting thread.
             * A thread is in the waiting state due to calling one of the
             * following methods:
             * <ul>
             *   <li>{@link Object#wait() Object.wait} with no timeout</li>
             *   <li>{@link #join() Thread.join} with no timeout</li>
             *   <li>{@link LockSupport#park() LockSupport.park}</li>
             * </ul>
             *
             * <p>A thread in the waiting state is waiting for another thread to
             * perform a particular action.
             *
             * For example, a thread that has called <tt>Object.wait()</tt>
             * on an object is waiting for another thread to call
             * <tt>Object.notify()</tt> or <tt>Object.notifyAll()</tt> on
             * that object. A thread that has called <tt>Thread.join()</tt>
             * is waiting for a specified thread to terminate.
             */
            WAITING,
    
            /**
             * Thread state for a waiting thread with a specified waiting time.
             * A thread is in the timed waiting state due to calling one of
             * the following methods with a specified positive waiting time:
             * <ul>
             *   <li>{@link #sleep Thread.sleep}</li>
             *   <li>{@link Object#wait(long) Object.wait} with timeout</li>
             *   <li>{@link #join(long) Thread.join} with timeout</li>
             *   <li>{@link LockSupport#parkNanos LockSupport.parkNanos}</li>
             *   <li>{@link LockSupport#parkUntil LockSupport.parkUntil}</li>
             * </ul>
             */
            TIMED_WAITING,
    
            /**
             * Thread state for a terminated thread.
             * The thread has completed execution.
             */
            TERMINATED;
        }
    
    • NEW:线程刚被创建,但是还没有调用 start() 方法
    • RUNNABLE:当调用了 start() 方法之后,Java API 层面的 RUNNABLE 状态涵盖了 操作系统 层面的可运行状态运行状态阻塞状态(由于 BIO 导致的线程阻塞,在 Java 里无法区分,仍然认为是可运行)
    • BLOCKED、WAITING、TIMED_WAITING:Java API 层面对阻塞状态的细分
    • TERMINATED:当线程代码运行结束
    @Slf4j
    public class StateTest {
        public static void main(String[] args) throws IOException {
            // new
            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...");
                }
            };
            // terminated
            t3.start();
    
            Thread t4 = new Thread("t4") {
                @Override
                public void run() {
                    synchronized (StateTest.class) {
                        try {
                            Thread.sleep(1000000);
                        } catch (InterruptedException e) {
                            e.printStackTrace();
                        }
                    }
                }
            };
            // timed_waiting
            t4.start();
    
            Thread t5 = new Thread("t5") {
                @Override
                public void run() {
                    try {
                        t2.join();
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }
            };
            // waiting
            t5.start();
    
            Thread t6 = new Thread("t6") {
                @Override
                public void run() {
                    synchronized (StateTest.class) {
                        try {
                            Thread.sleep(1000000);
                        } catch (InterruptedException e) {
                            e.printStackTrace();
                        }
                    }
                }
            };
            // blocked 拿不到锁
            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();
        }
    }
    
    15:16:58.719 [t3] DEBUG juc.thread.StateTest - running...
    15:16:59.230 [main] DEBUG juc.thread.StateTest - t1 state NEW
    15:16:59.238 [main] DEBUG juc.thread.StateTest - t2 state RUNNABLE
    15:16:59.238 [main] DEBUG juc.thread.StateTest - t3 state TERMINATED
    15:16:59.239 [main] DEBUG juc.thread.StateTest - t4 state TIMED_WAITING
    15:16:59.239 [main] DEBUG juc.thread.StateTest - t5 state WAITING
    15:16:59.239 [main] DEBUG juc.thread.StateTest - t6 state BLOCKED
    

    三、线程状态转换

    image.png

    1.NEW --> RUNNABLE

    当调用 t.start()方法时,由 NEW --> RUNNABLE

    2.RUNNABLE <--> WAITING

    t 线程用 synchronized(obj) 获取了对象锁后:

    • 调用 obj.wait() 方法时,t 线程从 RUNNABLE --> WAITING
    • 调用 obj.notify()obj.notifyAll()t.interrupt()
      竞争锁成功,t 线程从 WAITING --> RUNNABLE
      竞争锁失败,t 线程从 WAITING --> BLOCKED

    3.RUNNABLE <--> WAITING

    • 当前线程调用 t.join() 方法时,当前线程从 RUNNABLE --> WAITING(是当前线程在t 线程对象的监视器上等待)
    • t 线程运行结束,或调用了当前线程的 interrupt() 时,当前线程从 WAITING --> RUNNABLE

    4.RUNNABLE <--> WAITING

    • 当前线程调用 LockSupport.park() 方法会让当前线程从 RUNNABLE --> WAITING
    • 调用 LockSupport.unpark(目标线程) 或调用了线程 的 interrupt() ,会让目标线程从 WAITING -->RUNNABLE

    5.RUNNABLE <--> TIMED_WAITING

    t 线程用 synchronized(obj) 获取了对象锁后:

    • 调用 obj.wait(long n) 方法时,t 线程从 RUNNABLE --> TIMED_WAITING
    • t 线程等待时间超过了 n 毫秒,或调用 obj.notify()obj.notifyAll()t.interrupt()
      竞争锁成功,t 线程从 TIMED_WAITING --> RUNNABLE
      竞争锁失败,t 线程从 TIMED_WAITING --> BLOCKED

    6.RUNNABLE <--> TIMED_WAITING

    • 当前线程调用 t.join(long n) 方法时,当前线程从 RUNNABLE --> TIMED_WAITING(当前线程在t 线程对象的监视器上等待)
    • 当前线程等待时间超过了 n 毫秒,或t 线程运行结束,或调用了当前线程的 interrupt() 时,当前线程从TIMED_WAITING --> RUNNABLE

    7.RUNNABLE <--> TIMED_WAITING

    • 当前线程调用 Thread.sleep(long n) ,当前线程从 RUNNABLE --> TIMED_WAITING
    • 当前线程等待时间超过了 n 毫秒,当前线程从 TIMED_WAITING --> RUNNABLE

    8.RUNNABLE <--> TIMED_WAITING

    • 当前线程调用 LockSupport.parkNanos(long nanos)LockSupport.parkUntil(long millis) 时,当前线程从 RUNNABLE --> TIMED_WAITING
    • 调用 LockSupport.unpark(目标线程) 或调用了线程 的 interrupt() ,或是等待超时,会让目标线程从TIMED_WAITING--> RUNNABLE

    9.RUNNABLE <--> BLOCKED

    • t 线程用 synchronized(obj) 获取了对象锁时如果竞争失败,从 RUNNABLE --> BLOCKED
    • 持 obj 锁线程的同步代码块执行完毕,会唤醒该对象上所有 BLOCKED 的线程重新竞争,如果其中 t 线程竞争成功,从 BLOCKED --> RUNNABLE ,其它失败的线程仍然 BLOCKED

    10.RUNNABLE <--> TERMINATED

    当前线程所有代码运行完毕,进入 TERMINATED

    相关文章

      网友评论

        本文标题:线程的状态

        本文链接:https://www.haomeiwen.com/subject/tvhgwdtx.html