最近好几个同事都向我问起过java线程转储方面的知识,都是些常见的问题,如:系统负载过高,系统吞吐率降低,系统挂起等等。这些问题的定位和解决都离不开线程转储,因为这些问题在测试环境复现的难度较大,只有在生产环境进行ThreadDump,才能快速定位问题。
线程状态
在具体分析线程转储数据之前,我们首先要明确线程的状态。java.lang.Thread.State枚举类中定义了如下几种类型:
- NEW:线程创建尚未启动。
- RUNNABLE:包括操作系统线程状态中的Ready和Running,可能在等待时间片或者正在执行。
- BLOCKED:线程被阻塞。
- WAITING:不会分配CPU执行时间,直到别的线程显式的唤醒,否则无限期等待。LockSupport.park(),没有设置Timeout参数的Object.wait()和Thread.join(),会导致此现象。
- TIMED_WAITING:不会分配CPU执行时间,直到系统自动唤醒,不需要别的线程显示唤醒。Thread.sleep(),LockSupport.parkNanos(),LockSupport.parkUntil(),设置了超时时间的Object.wait()和Thread.join(),会让线程进入有限期等待。
- TERMINATED:线程执行结束。