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 河北王校长 的知识分享