当我们用jstack查看Java线程状态时,会看到各种线程状态。当发生IO等待时(比如远程调用时),线程是什么状态呢,Blocked还是Waiting?
答案是Runnable状态,是不是有些出乎意料!实际上,在操作系统层面Java的Runnable状态除了包括Running状态,还包括Ready(就绪状态,等待CPU调度)和IO Wait等状态。
如上图,Runnable状态的注解明确说明了,在JVM层面执行的线程,在操作系统层面可能在等待其他资源。如果等待的资源是CPU,在操作系统层面线程就是等待被CPU调度的Ready状态;如果等待的资源是磁盘网卡等IO资源,在操作系统层面线程就是等待IO操作完成的IO Wait状态。
有人可能会问,为什么Java线程没有专门的Running状态呢?
目前绝大部分主流操作系统都是以时间分片的方式对任务进行轮询调度,时间片通常很短,大概几十毫秒,也就是说一个线程每次在cpu上只能执行几十毫秒,然后就会被CPU调度出来变成Ready状态,等待再一次被CPU执行,线程在Ready和Running两个状态间快速切换。通常情况,JVM线程状态主要为了监控使用,是给人看的。当你看到线程状态是Running的一瞬间,线程状态早已经切换N次了。所以,再给线程专门加一个Running状态也就没什么意义了。