JUC源码讲解:线程状态转换

JUC源码讲解:线程状态转换

抛出问题

一个线程,有七种(也可以说是六种)状态,究竟是哪七种呢?在什么条件下,线程会进入一个状态,又在什么条件下,线程转而进入另一种状态呢?下面我们从源码角度看一下线程的状态转换

观察源码

我们进去 Thread.State.class 中,可以看到,线程状态由一个 enum 定义

感兴趣的朋友可以去看看源码的注释,写的很详细

public enum State {

        NEW,

        RUNNABLE,

        BLOCKED,

        WAITING,

        TIMED_WAITING,

        TERMINATED;
    }

观察看到,enum中定义了六种状态,我们来解释一下 :

  • NEW: 实例化, 调用 Thread.start() 后,会进入 RUNNABLE 状态,然后...... -->

  • RUNNABLE: 运行。这里的 RUNNABLE 又可细分为 RUNNING(运行中)和 READY(就绪)两种状态,这两种状态一直在相互转换,详见 -->

    • RUNNING: 运行中。当线程已经获取到了CPU时间片时,会呈现出这个状态,当没有被分配到CPU时间片或调用了 yield(), 会进入 READY 状态 -->
    • READY:就绪,当线程没有获取到CPU时间片、或在RUNNING时调用了 yield(),会呈现出这个状态。当获取了CPU时间片时,会回转移到 RUNNING 状态 <--
  • BLOCKED:阻塞。进入加锁的代码块会阻塞,注意,只有 sync 才会导致线程进入这个状态,其他的锁lock锁并不会!

  • WAITING:等待。线程在 RUNNABLE 状态中使用 Object.wait(), Thread.join(), LockSupport.partk() 会使线程进入这个状态,当使用 Object.notify(), Object.notifAll(), LockSupport.unpark(Thread) 释放,又会返回到 RUNNABLE 状态。注意,为什么 join() 可以用 notify(), notifyAll() 释放呢?因为 joint() 源码里用的其实就是 notify() !

  • TIMEED_WAITING: 超时等待。当使用 Thread.sleep(long), Object.wait(long), Thread.join(long), LockSupport.parkNanos(), LockSupport.partUntil() 时会进入这个状态,使用 Object.notify(), Object.notifyAll(), LockSupport.unpark(Thread) 释放后会回到 RUNNABLE 状态

  • TERMINTED: 终止。执行完成

好了,以上这段文字就是对七个线程状态的解释,他们是什么作用,如何相互转换的,解释的非常详细了,源码中写的也比较详细,注意一下我提到的那几点就可以了

总结

在Thread.State.class 中,线程用 enum 被定义为六种状态,而之所以说线程有七种状态的原因是,其中的 RUNNABLE 又可以细分为 READY 和 RUNNING 两种状态,这是因为考虑到一些线程没有争抢到CPU时间片而细分出的两种状态,这两种状态是在互相转换的,他们都属于 RUNNABLE

以上就是对线程七种状态的详细解读了,希望大家有所收获

感谢B站up 河北王校长 的知识分享

posted @ 2024-03-12 20:23  yangruomao  阅读(6)  评论(0编辑  收藏  举报