Java Thread Status
上图是早期进程的状态,这里所谓“进程状态”指早期的那种“单线程进程”的状态。
对于现在普遍的“多线程进程”,显然,谈论“进程状态”已经没有意义,应该谈论“进程下某个线程的状态”或者直接说“线程状态”。
这里有个误区:其实在 Java 里面,线程是包含6个状态,而不是5个状态。
1 | /* |
These states are virtual machine states which do not reflect any operating system thread states。
这些状态是虚拟机状态,它不反映任何操作系统的线程状态。
Runnable 与 传统Running 状态的区别
有人常觉得 Java 线程状态中还少了个 Running 状态,这其实是把两个不同层面的状态混淆了。对 Java 线程状态而言,不存在所谓的 Running 状态,它的 Runnable 状态包含了 Running 状态。
为何 JVM 中没有去区分这两种状态呢?现在的时分(time-sharing)多任务(multi-task)操作系统架构通常都是用所谓的“时间分片(time quantum or time slice)”方式进行抢占式(preemptive)轮转调度(round-robin式)。这个时间分片通常是很小的,一个线程一次最多只能在 CPU 上运行比如 10-20ms 的时间(此时处于 Running 状态),也即大概只有 0.01 秒这一量级,时间片用后就要被切换下来放入调度队列的末尾等待再次调度(也即回到 Ready 状态)。
Java中的 RUNNABLE 状态实际上是包含了 Ready 与 Running 的状态的。
从实际来说,线程只有”就绪”、”阻塞”、”运行”三种状态:
- 运行状态,线程正在干活的状态;
- 就绪状态,CPU正在忙活别的;
- 阻塞状态,线程主动让出CPU资源;
NEW 和 TERMINATED 这两种状态其实并不是线程的状态,而是java.lang.Thread对象的状态。可以说,处于 NEW 和 TERMINATED 状态的”线程”其实并不是线程,而只是一个代表着线程对象而已。
所以我们把 NEW 和 TERMINATED 两种状态去掉,那么Java定义的线程状态还有4种:
- RUNNABLE
- BLOCKED
- WAITING
- TIMED_WAITING
这四种状态怎么对应到”就绪”、”阻塞”、”运行”这三种状态里呢:
- RUNNABLE,对应”就绪”和”运行”两种状态,也就是说处于就绪和运行状态的线程在java.lang.Thread中都表现为”RUNNABLE”;
- BLOCKED,对应”阻塞”状态,此线程需要获得某个锁才能继续执行,而这个锁目前被其他线程持有,所以进入了被动的等待状态,直到抢到了那个锁,才会再次进入”就绪”状态;
- WAITING,对应”阻塞”状态,代表此线程正处于无限期的主动等待中,直到有人唤醒它,它才会再次进入就绪状态;
- TIMED_WAITING,对应”阻塞”状态,代表此线程正处于有限期的主动等待中,要么有人唤醒它,要么等待够了一定时间之后,才会再次进入就绪状态;
Reference
- [java线程运行怎么有第六种状态?] https://www.zhihu.com/question/56494969