问题描述
请教一下 JStack中的wait on condition是什么意思?我发现,某个线程在jstack中被标识为“wait on condition”时,下面的线程状态,有时候是:“RUNNABLE”,也有的时候是:“TIMED_WAITING”至于其他状态,应该也有,只是我只简单看到这两个而已。那个这个“wait on condition”在jstack中究竟是什么含义呢?JStack对应的信息在JConsole中一样可以查看。但是在JConsole中并没有给出“wait on condition”的概念。另外,jconsole的查看到的线程信息,来源是MBean中的java.lang.management.ThreadMXBean的线程描述信息:java.lang.management.ThreadInfo这一点确信无异。(这一点我猜测是JMX通过不同的连接器发布出来的) 问题补充:我在网上搜索找到一篇文章:http://www.cnblogs.com/zhengyun_ustc/archive/2013/01/06/dumpanalysis.html但是我觉得这篇文章概念有些混乱。 尤其在说到线程状态的时候,请严格按照JVM规范来描述。按照约定,线程状态只有以下几种:NEW 至今尚未启动的线程的状态(jstack不讨论此类线程)RUNNABLE 可运行线程的线程状态。处于可运行状态的某一线程正在 Java 虚拟机中运行,但它可能正在等待操作系统中的其他资源,比如处理器。BLOCKED 受阻塞并且正在等待监视器锁的某一线程的线程状态。(比如synchronized (lock) {}而lock被其他线程持有时,当前线程就会进入BLOCKED状态)WAITING 描述非常清楚,包括3种情况: 不带超时值的 Object.wait 不带超时值的 Thread.join LockSupport.park TIMED_WAITING 以下5种情况: Thread.sleep 带有超时值的 Object.wait 带有超时值的 Thread.join LockSupport.parkNanos LockSupport.parkUntil TERMINATED 线程已终止(jstack不讨论此情况)我所引用的文章对这些概念描述很混乱。 要讨论请使用严谨的专业术语。
解决方案
引用该状态出现在线程等待某个条件的发生。具体是什么原因,可以结合 stacktrace来分析。最常见的情况是线程在等待网络的读写,比如当网络数据没有准备好读时,线程处于这种等待状态,而一旦有数据准备好读之后,线程会重新激活,读取并处理数据。在 Java引入 NewIO之前,对于每个网络连接,都有一个对应的线程来处理网络的读写操作,即使没有可读写的数据,线程仍然阻塞在读写操作上,这样有可能造成资源浪费,而且给操作系统的线程调度也带来压力。在 NewIO里采用了新的机制,编写的服务器程序的性能和可扩展性都得到提高。 如果发现有大量的线程都在处在 Wait on condition,从线程 stack看, 正等待网络读写,这可能是一个网络瓶颈的征兆。因为网络阻塞导致线程无法执行。一种情况是网络非常忙,几 乎消耗了所有的带宽,仍然有大量数据等待网络读 写;另一种情况也可能是网络空闲,但由于路由等问题,导致包无法正常的到达。所以要结合系统的一些性能观察工具来综合分析,比如 netstat统计单位时间的发送包的数目,如果很明显超过了所在网络带宽的限制 ; 观察 cpu的利用率,如果系统态的 CPU时间,相对于用户态的 CPU时间比例较高;如果程序运行在 Solaris 10平台上,可以用 dtrace工具看系统调用的情况,如果观察到 read/write的系统调用的次数或者运行时间遥遥领先;这些都指向由于网络带宽所限导致的网络瓶颈。另外一种出现 Wait on condition的常见情况是该线程在 sleep,等待 sleep的时间到了时候,将被唤醒参见:http://jameswxx.iteye.com/blog/1041173