【问题标题】:What does "Lock released while waiting:" mean in a Java thread dump?Java 线程转储中的“等待时释放锁:”是什么意思?
【发布时间】:2011-06-15 14:11:43
【问题描述】:

在这个线程转储中:

INFO   | jvm 3    | 2011/06/08 13:36:12 | "ExecuteThread: '38' for queue: 'default'" id=55 idx=0x78 tid=5316 prio=5 alive, in native, waiting, daemon
INFO   | jvm 3    | 2011/06/08 13:36:12 |     -- Waiting for notification on: weblogic/ejb20/locks/ExclusiveLockManager$LockWaiter@0x25EF8828[fat lock]
INFO   | jvm 3    | 2011/06/08 13:36:12 |     at jrockit/vm/Threads.waitForSignal(J)Z(Native Method)
INFO   | jvm 3    | 2011/06/08 13:36:12 |     at java/lang/Object.wait(J)V(Native Method)[optimized]
INFO   | jvm 3    | 2011/06/08 13:36:12 |     at weblogic/ejb20/locks/ExclusiveLockManager$LockBucket.lock(Ljava/lang/Object;Ljava/lang/Object;I)Z(ExclusiveLockManager.java:504)[optimized]
INFO   | jvm 3    | 2011/06/08 13:36:12 |     ^-- Lock released while waiting: weblogic/ejb20/locks/ExclusiveLockManager$LockWaiter@0x25EF8828[fat lock]
INFO   | jvm 3    | 2011/06/08 13:36:12 |     at weblogic/ejb20/locks/ExclusiveLockManager.lock(Ljava/lang/Object;Ljava/lang/Object;I)Z(ExclusiveLockManager.java:261)[optimized]
INFO   | jvm 3    | 2011/06/08 13:36:12 |     at weblogic/ejb20/manager/ExclusiveEntityManager.acquireLock(Ljava/lang/Object;Ljavax/transaction/Transaction;I)Z(ExclusiveEntityManager.java:210)[inlined]
INFO   | jvm 3    | 2011/06/08 13:36:12 |     at weblogic/ejb20/manager/ExclusiveEntityManager.getReadyBean(Ljava/lang/Object;Ljavax/transaction/Transaction;I)Ljavax/ejb/EntityBean;(ExclusiveEntityManager.java:267)[inlined]
INFO   | jvm 3    | 2011/06/08 13:36:12 |     at weblogic/ejb20/manager/ExclusiveEntityManager.preInvoke(Lweblogic/ejb20/internal/InvocationWrapper;)Ljavax/ejb/EnterpriseBean;(ExclusiveEntityManager.java:242)[optimized]
INFO   | jvm 3    | 2011/06/08 13:36:12 |     at weblogic/ejb20/internal/BaseEJBObject.preInvoke(Lweblogic/ejb20/internal/InvocationWrapper;Lweblogic/security/service/ContextHandler;)Lweblogic/ejb20/internal/InvocationWrapper;(BaseEJBObject.java:152)[inlined]
INFO   | jvm 3    | 2011/06/08 13:36:12 |     at weblogic/ejb20/internal/EntityEJBObject.preInvoke(Lweblogic/ejb20/internal/MethodDescriptor;Lweblogic/security/service/ContextHandler;)Lweblogic/ejb20/internal/InvocationWrapper;(EntityEJBObject.java:104)[inlined]
INFO   | jvm 3    | 2011/06/08 13:36:12 |     at foob/ejb/commodity/ejb_Commodity_etfd4i_EOImpl.getData()Lfoob/ejb/commodity/db/CommodityData;(ejb_Commodity_etfd4i_EOImpl.java:701)[optimized]
INFO   | jvm 3    | 2011/06/08 13:36:12 |     at foob/ejb/item/OurItem.loadCommodityData()V(OurItem.java:172)[optimized]
INFO   | jvm 3    | 2011/06/08 13:36:12 |     ^-- Holding lock: java/lang/Class@0x067EA070[fat lock]
INFO   | jvm 3    | 2011/06/08 13:36:12 |     at foob/ejb/item/OurItem.getCommodityData()Lfoob/ejb/commodity/db/CommodityData;(OurItem.java:251)
INFO   | jvm 3    | 2011/06/08 13:36:12 |     at foob/ejb/item/OurItem.getTheControlGid()Ljava/lang/String;(OurItem.java:259)
INFO   | jvm 3    | 2011/06/08 13:36:12 |     at foob/business/shipment/OurThing.getTheControlGid(Lfoob/util/jdbc/OurConnection;)Ljava/lang/String;(OurThing.java:379)

行是什么

Lock released while waiting: weblogic/ejb20/locks/ExclusiveLockManager$LockWaiter@0x25EF8828

是什么意思?我们有 8 个其他线程阻塞等待 java/lang/Class@0x067EA070 被释放,这个线程正在持有,但我不明白这个线程阻塞了什么,也不知道锁被释放是什么意思。我会认为线程转储是一种停止世界类型的事件,因此有问题的行不会指线程转储发生时释放的锁......

此外,它出现的位置是否有任何意义(即它上面和下面的线)?

显然,我不是 Java 期望,所以我希望这不是一个太愚蠢的问题。感谢您的帮助!

【问题讨论】:

  • “线程转储是一种停止世界的事件”。不,不是。它只是 JVM 中某个点处执行的所有线程的堆栈帧的转储。它可能在诸如 JVM 崩溃之类的世界末日类型的事件发生时生成。 编辑:您可以通过向 JVM 进程发送 SIGBREAK 来获取线程转储。
  • Vineet - “stop-the-world”是指 JVM 中的所有执行都暂停,线程转储被执行,然后所有执行恢复。一些 GC 的行为是这样的。
  • 好吧,从这个意义上说你是对的。我以不同的方式解释它。
  • 这是哪个版本的 WebLogic?
  • @Vineet -- 我不确定,我认为是 8.0.4 或 8.0.6。

标签: java ejb-2.x weblogic8.x


【解决方案1】:

来自Oracle JRockit JDK Tools Guide,

等待的语义(对于 通知)在 Java 中的对象是 有点复杂。首先,输入一个 同步块,你必须采取 锁定对象,然后调用 wait() 在那个对象上。在等待中 方法,锁在之前被释放 线程进入睡眠状态等待 通知。当线程接收 一个通知,wait() 重新接收 返回前锁定。如果一个线程有 拿了锁,正在等待 关于那个锁的通知,这条线 在描述何时的堆栈跟踪中 锁定未显示为 (持锁); 显示为(锁定 等待时释放。)

换句话说,这意味着该线程有一个对象,该对象较早获得了锁,然后在调用object.wait()时释放了它。类似行为的代码模式是:

synchronized(lock) //acquires the lock
{
   ...
   do some work
   ...
   object.wait(); //releases the lock, and waits for a notification
}

更新

在查看堆栈跟踪时,您似乎正在使用实体 EJB Bean,并且考虑到此类实现的操作方式,通常会在实体 EJB 上获取锁。这实际上取决于用于管理必须访问数据库的并发事务的concurrency strategy。我会怀疑 bean 的数量太少,或者只有一个 bean 可以锁定。

【讨论】:

【解决方案2】:

在此页面上搜索“已释放锁定”,它可以很好地解释在等待对象的逻辑中发生的情况。

http://download.oracle.com/docs/cd/E13188_01/jrockit/docs142/userguide/apstkdmp.html

似乎这条消息表示当原始的 wait() 调用被 notify() 重新捕获对象的锁时。

为了将来参考,我只是通过谷歌搜索“等待时释放锁定”找到了这个,这是出现的第一页......希望你已经在网上搜索过并且不满意用你找到的东西,在这种情况下,如果这没有帮助,我很抱歉。

【讨论】:

  • 是的,我在发帖前用谷歌搜索了大约半小时,但没有找到。通常我有疯狂的谷歌搜索技能,但他们今天一定抛弃了我——谢谢!
【解决方案3】:

很可能与上面两行的条目有关:

at java/lang/Object.wait(J)V(Native Method)[optimized]

wait() 将释放当前持有的锁(被周围同步块持有的锁)并等待一个 notify() 信号。

【讨论】:

    猜你喜欢
    • 2012-01-23
    • 1970-01-01
    • 1970-01-01
    • 2013-12-11
    • 2011-10-27
    • 2012-07-05
    • 2021-04-12
    • 2017-10-31
    • 1970-01-01
    相关资源
    最近更新 更多