jdk里面定义的线程状态有:
public enum State { NEW, RUNNABLE, BLOCKED, WAITING, TIMED_WAITING, TERMINATED; }
但是jstack里面输出的就没有这么简洁,问题追踪变得复杂
首先看一下线程状态轮换图
虽然线程状态整体分为:NEW, RUNNABLE, BLOCKED, WAITING, TIMED_WAITING, TERMINATED,但是这个粒度太粗了,甚至不知道什么导致的WAITING。
(一). 较容易理解的线程状态引起原因
1. BLOCKED (on object monitor)
2个线程获取同一个锁,A线程得到锁并占有,那么B线程就是此种状态
2. WAITING (on object monitor)、TIMED_WAITING (on object monitor)
线程调用了wait调用了,等待被唤醒。TIMED_WAITING (on object monitor)调用了带时间的wait方法。
3. TIMED_WAITING (parking)、TIMED_WAITING (on object monitor)
线程调用了park方法,TIMED_WAITING (parking)调用了带时间的park方法
4. TIMED_WAITING (sleeping)
线程调用了sleep方法,WAITING是不存在sleeping的,因为sleep方法都带时间参数
(二). 不容易理解的线程状态引起原因
1. waiting on condition
此种行为,表面线程在等待一个资源,比如http网络请求阻塞了等,要注意此种现象
2. Runnable
此种状态最容易理解,实践表面如果线程一直是此种状态,通过多次jstack如果发现一直处在一个方法上,那也应该是有问题,比如说死循环,网络请求(有的网络请求不一定看起来就是阻塞现象,因为它一直在运行)
一般CPU很忙时,则关注runnable的线程,CPU很闲时,则关注waiting for monitor entry的线程。