【问题标题】:Java thread dump: WAITING (on object monitor) - what is it waiting on?Java 线程转储:WAITING(在对象监视器上)- 它在等待什么?
【发布时间】:2014-10-31 08:14:42
【问题描述】:

java-thread-dump-waiting-on-object-monitor-line-not-followed-by-waiting-on 也有类似的问题,但没有具体的答案,所以我会问我的问题,希望能获得更多信息...

在下面的线程转储中,我看到线程处于“WAITING (on object monitor)”状态——但没有“waiting on”表示它正在等待什么。如何解释这个线程堆栈并找出这个线程等待的原因(以及什么资源)?

"eventTaskExecutor-50" prio=10 tid=0x0000000004117000 nid=0xd8dd in Object.wait() [0x00007f8f457ad000]
java.lang.Thread.State: WAITING (on object monitor)
at java.lang.Object.wait(Native Method)
at java.lang.Object.wait(Object.java:503)
at com.tibco.tibjms.TibjmsxLink.sendRequest(TibjmsxLink.java:359)
- locked <0x00007f98cbebe5d8> (a com.tibco.tibjms.TibjmsxResponse)
at com.tibco.tibjms.TibjmsxSessionImp._confirmTransacted(TibjmsxSessionImp.java:2934)
at com.tibco.tibjms.TibjmsxSessionImp._confirm(TibjmsxSessionImp.java:3333)
- locked <0x00007f90101399b8> (a java.lang.Object)
at com.tibco.tibjms.TibjmsxSessionImp._commit(TibjmsxSessionImp.java:2666)
at com.tibco.tibjms.TibjmsxSessionImp.commit(TibjmsxSessionImp.java:4516)
at org.springframework.jms.support.JmsUtils.commitIfNecessary(JmsUtils.java:217)
at org.springframework.jms.listener.AbstractMessageListenerContainer.commitIfNecessary(AbstractMessageListenerContainer.java:577)
at org.springframework.jms.listener.AbstractMessageListenerContainer.doExecuteListener(AbstractMessageListenerContainer.java:482)
at org.springframework.jms.listener.AbstractPollingMessageListenerContainer.doReceiveAndExecute(AbstractPollingMessageListenerContainer.java:325)
at org.springframework.jms.listener.AbstractPollingMessageListenerContainer.receiveAndExecute(AbstractPollingMessageListenerContainer.java:263)
at org.springframework.jms.listener.DefaultMessageListenerContainer$AsyncMessageListenerInvoker.invokeListener(DefaultMessageListenerContainer.java:1102)
at org.springframework.jms.listener.DefaultMessageListenerContainer$AsyncMessageListenerInvoker.run(DefaultMessageListenerContainer.java:996)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1145)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:615)
at java.lang.Thread.run(Thread.java:722)

Locked ownable synchronizers:
- <0x00007f901011ca88> (a java.util.concurrent.ThreadPoolExecutor$Worker)

此线程是配置为接受来自 Tibco 总线的消息的侦听器线程之一。

谢谢!

码头

【问题讨论】:

    标签: multithreading jvm thread-dump


    【解决方案1】:

    这是 HotSpot JVM 的一个特性。转储堆栈时,JVM 从方法局部变量中恢复等待对象。此信息可用于解释方法,但不适用于已编译的本机包装器。

    Object.wait 足够频繁地执行时,它会被 JIT 编译。
    之后,线程转储中将没有 “waiting on” 行。

    1. 由于必须在synchronized 对象上调用wait(),因此等待对象通常是堆栈跟踪中最后一个锁定的对象。你的情况是

      - locked <0x00007f98cbebe5d8> (a com.tibco.tibjms.TibjmsxResponse)
      
    2. 要防止 Object.wait 被 JIT 编译(从而使等待信息始终可用),请使用以下 JVM 选项

      -XX:CompileCommand="exclude,java/lang/Object.wait" 
      

    【讨论】:

    • @YuFengShen 括号内打印的内容与等待对象无关。 0x00007f8f457ad000 是给定线程的最后一个已知 Java 堆栈帧的地址。
    • apangin ,请问为什么等待的对象地址不在打印的顶行“Object.wait() [0x00007f8f457ad000]”,也就是说它在0x00007f8f457ad000?
    • 非常有用的意见。我有一个很好的 JVM 选项 - (-XX:CompileCommand="exclude,java/lang/Object.wait" )
    【解决方案2】:

    此线程正在等待来自另一个线程的通知(线程名称是 TCPLinkReader,如果您查看完整的线程转储,您应该能够找到它),该线程由 TIBCO EMS 客户端库创建。

    堆栈跟踪显示 Spring 应用程序正在尝试提交会话。提交会话 EMS 客户端需要向服务器发送一些数据并等待服务器确认会话是否成功提交。

    TCPLinkReader 线程是 EMS 客户端用来接收下游(从服务器到客户端)TCP 数据包的专用线程。

    如果你看到这个话题持续很长时间,有两种情况:

    • EMS 服务器端出现问题,可能挂起

    • 客户端库有一些缺陷导致死锁,所以服务器确实发回了响应,但 TCPLinkReader 线程没有通知调用者线程。

    最后,如果问题仍然存在,请发布完整的线程转储。

    【讨论】:

    • 令人惊讶的是,我在线程转储中没有看到任何 TCPLinkReader 线程......但是,您对情况的评估似乎是正确的,因为我也怀疑我们看到的问题与他有关与 Tibco 总线通信...感谢您提供的信息!
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2011-07-17
    • 2011-03-09
    • 1970-01-01
    • 2012-08-03
    • 2013-12-11
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多