JVM把线程分为6种状态,分别是新建(New)、运行(Runnable)、无期限等待(Waiting)、一定时间的等待(Timed Waiting)、阻塞(Blocked)、结束退出(Terminated),如下图:
新建(New): 线程创建后还未启动
运行(Runnable): 包括了Ready和Running两种状态,也就是说此状态的线程可能在等待CPU执行权,也可能正在执行
无期限等待(Waiting): 处于此种状态的线程不会被分配CPU执行时间,它们要等待其它线程显示的唤醒,即调用notify()或notifyAll()方法。以下方法会让线程进入无期限等待状态:
没有设置参数的wait()方法,即wait(0)方法
没有设置参数的join()方法,即join(0)方法
LockSupport.park()方法
一定时间的等待(Timed Waiting): 处于这种状态的线程也不会被分配CPU的执行权,不过它不需要等待其它线程的唤醒,在一定时间后它们会由系统自动唤醒,以下方法会让线程进入有时间的等待:
sleep()方法
设置了参数的wait()方法
设置了参数的join()方法
LockSupport.parkNanos()方法
LockSupport.parkUntil()方法
阻塞(Blocked): 线程被阻塞了,在程序等待进入同步区域的时候处于这种状态。阻塞状态与等待状态的区别是阻塞状态在等待着获取到一个排它锁,这个事件将在另外一个线程放弃这个锁时发生,而等待状态是在等待一段时间或者被唤醒动作发生。
结束退出(Terminated): 线程运行结束或终止。
JVM线程分析工具
jstack: jstack(stack trace for java),java堆栈跟踪工具,用于生成JVM当前时刻的线程快照,用于定位线程出现长时间停顿的原因,如线程死锁、死循环、请求外部资源导致长时间的等待等原因。
jstack命令格式:
jstack [option] JVM进程号
option参数为:
-F:当正常输出的请求不被响应,强制输出线程堆栈
-l:除堆栈外,显示关于锁的附加信息
-m:如果调用到本地方法的话,可以显示C/C++的堆栈
如下代码为查看tomcat的线程(只显示部分):
[root@java ~]# jstack -l 24685
2012-12-05 17:03:17
Full thread dump Java HotSpot(TM) 64-Bit Server VM (20.5-b03 mixed mode):
"Attach Listener" daemon prio=10 tid=0x00007fb278001000 nid=0x1924 waiting on condition [0x0000000000000000]
java.lang.Thread.State: RUNNABLE
Locked ownable synchronizers:
- None
"TP-Monitor" daemon prio=10 tid=0x00007fb2a035a000 nid=0x60a8 in Object.wait() [0x00007fb29c1f0000]
java.lang.Thread.State: TIMED_WAITING (on object monitor)
at java.lang.Object.wait(Native Method)
- waiting on <0x00000000e0634468> (a org.apache.tomcat.util.threads.ThreadPool$MonitorRunnable)
at org.apache.tomcat.util.threads.ThreadPool$MonitorRunnable.run(ThreadPool.java:565)
- locked <0x00000000e0634468> (a org.apache.tomcat.util.threads.ThreadPool$MonitorRunnable)
at java.lang.Thread.run(Unknown Source)
Locked ownable synchronizers:
- None
......
VisualVM: JVM强大的图形界面分析工具,如下图查看Eclipse的运行,该工具可以查看到监控的进程中所有线程的执行状态
该文章学习 周志明 深入理解Java虚拟机 JVM高级特性与最佳实践 记录