非常不寻常的情况 - 线程被锁定在它所持有的锁上?

时间:2008-12-03 10:00:36

标签: java locking

我正在研究的这个java程序似乎在启动时挂起,所以我尝试使用jconsole来调试问题。 事实证明它正在等待对声明为 -

的方法的调用
synchronized void stopQuery()

但是这里是疯狂的部分,'同步'方法的锁已经被阻塞的线程所持有。 我在执行getThreadInfo()MXBean方法后附加了JConsole的截图。

请注意,lockOwnerId和threadId是一样的!这怎么可能呢?

alt text

编辑:
  Link 到这种情况的堆栈跟踪之一。 请注意,在查看堆栈跟踪后,即使'org.eclipse.jdt.internal.ui.text.JavaReconciler'线程也试图锁定到同一个DiskIndex对象,但是如果你查看对象地址,你会看到看到它实际上是一个不同的DiskIndex对象。

编辑2:
  Another Link 我在复制此问题时获得的不同堆栈跟踪。将两者进行比较以了解常见情况应该会有所帮助。

5 个答案:

答案 0 :(得分:2)

这看起来像是一个特别令人讨厌的僵局。没有更多信息,很难确定。这是我在没有代码的情况下看到的,但是:

在“文本查看器悬停演示者”和“工作者-3”之间可能存在死锁(或至少争用)对象引用0x00002aace2276720,而“Worker-3”持有对引用0x00002aace2276ad0的锁定。

这第二个引用似乎是一堆被阻塞线程的原因(特别是“Worker-4”,“Worker-1”和“Worker-0”)。

我的建议是检查ASTProvider.java第450行(请参阅前两个堆栈跟踪,其中似乎持有可疑对象锁,但似乎没有超过wait())。我还建议尝试将可执行文件锁定到单个核心(假设这是一个多核系统)。

看起来值得测试的下一段代码是SelectionListenerWithASTManager.java第153行(其中引用0x00002aace2276ad0被锁定,导致Workers阻塞)。

0x00002aace2276720的储物柜:

"Text Viewer Hover Presenter" daemon prio=10 tid=0x00002aad20166400 nid=0x51f4 in Object.wait() [0x000000004254c000..0x000000004254dd90]
   java.lang.Thread.State: WAITING (on object monitor)
    at java.lang.Object.wait(Native Method)
    - waiting on <0x00002aace2276720> (a java.lang.Object)
    at java.lang.Object.wait(Object.java:485)
    at org.eclipse.jdt.internal.ui.javaeditor.ASTProvider.getAST(ASTProvider.java:450)
    - locked <0x00002aace2276720> (a java.lang.Object)
    at org.eclipse.jdt.ui.SharedASTProvider.getAST(SharedASTProvider.java:129)
    at org.eclipse.jdt.internal.ui.text.java.hover.NLSStringHover.getHoverInfo(NLSStringHover.java:87)
    at org.eclipse.jdt.internal.ui.text.java.hover.AbstractJavaEditorTextHover.getHoverInfo2(AbstractJavaEditorTextHover.java:86)
    at org.eclipse.jdt.internal.ui.text.java.hover.BestMatchHover.getHoverInfo2(BestMatchHover.java:129)
    at org.eclipse.jdt.internal.ui.text.java.hover.JavaEditorTextHoverProxy.getHoverInfo2(JavaEditorTextHoverProxy.java:82)
    at org.eclipse.jface.text.TextViewerHoverManager$4.run(TextViewerHoverManager.java:166)

"Worker-3" prio=10 tid=0x00002aad132c3800 nid=0x5166 in Object.wait() [0x0000000042249000..0x000000004224ab10]
   java.lang.Thread.State: WAITING (on object monitor)
    at java.lang.Object.wait(Native Method)
    - waiting on <0x00002aace2276720> (a java.lang.Object)
    at java.lang.Object.wait(Object.java:485)
    at org.eclipse.jdt.internal.ui.javaeditor.ASTProvider.getAST(ASTProvider.java:450)
    - locked <0x00002aace2276720> (a java.lang.Object)
    at org.eclipse.jdt.ui.SharedASTProvider.getAST(SharedASTProvider.java:129)
    at org.eclipse.jdt.internal.ui.viewsupport.SelectionListenerWithASTManager$PartListenerGroup.calculateASTandInform(SelectionListenerWithASTManager.java:168)
    at org.eclipse.jdt.internal.ui.viewsupport.SelectionListenerWithASTManager$3.run(SelectionListenerWithASTManager.java:153)
    - locked <0x00002aace2276ad0> (a java.lang.Object)
    at org.eclipse.core.internal.jobs.Worker.run(Worker.java:55)

阻止在0x00002aace2276ad0

"Worker-4" prio=10 tid=0x00002aad132c4000 nid=0x5167 waiting for monitor entry [0x000000004234b000..0x000000004234bc90]
   java.lang.Thread.State: BLOCKED (on object monitor)
    at org.eclipse.jdt.internal.ui.viewsupport.SelectionListenerWithASTManager$3.run(SelectionListenerWithASTManager.java:153)
    - waiting to lock <0x00002aace2276ad0> (a java.lang.Object)
    at org.eclipse.core.internal.jobs.Worker.run(Worker.java:55)

"Worker-1" prio=10 tid=0x00002aad12835800 nid=0x5164 waiting for monitor entry [0x0000000041a42000..0x0000000041a42a10]
   java.lang.Thread.State: BLOCKED (on object monitor)
    at org.eclipse.jdt.internal.ui.viewsupport.SelectionListenerWithASTManager$3.run(SelectionListenerWithASTManager.java:153)
    - waiting to lock <0x00002aace2276ad0> (a java.lang.Object)
    at org.eclipse.core.internal.jobs.Worker.run(Worker.java:55)

"Worker-0" prio=10 tid=0x00002aad11a0ac00 nid=0x5146 waiting for monitor entry [0x0000000041941000..0x0000000041941d90]
   java.lang.Thread.State: BLOCKED (on object monitor)
    at org.eclipse.jdt.internal.ui.viewsupport.SelectionListenerWithASTManager$3.run(SelectionListenerWithASTManager.java:153)
    - waiting to lock <0x00002aace2276ad0> (a java.lang.Object)
    at org.eclipse.core.internal.jobs.Worker.run(Worker.java:55)

答案 1 :(得分:0)

这个方法是递归的吗?也许你在其中使用了一个需要同样方法的对象?

答案 2 :(得分:0)

但是对同步方法的锁是可重入的,这意味着如果一个持有该对象锁的线程试图再次锁定它,它将始终成功。

答案 3 :(得分:0)

可能值得尝试死锁检测代码 - like this

stopQuery锁似乎没有先前在堆栈跟踪中获取锁,但是那个锁似乎也没有在其他任何地方获得 - 很奇怪......

"Worker-2" prio=10 tid=0x00002aad1da66400 nid=0x5165 waiting for monitor entry [0x0000000041b43000..0x0000000041b43b90]
   java.lang.Thread.State: BLOCKED (on object monitor)
    at org.eclipse.jdt.internal.core.index.DiskIndex.stopQuery(DiskIndex.java)
    - waiting to lock <0x00002aacdfe83ea8> (a org.eclipse.jdt.internal.core.index.DiskIndex)
    at org.eclipse.jdt.internal.core.index.Index.stopQuery(Index.java:192)

在这个位上等待一个持有的锁,但是这会释放锁直到它获得通知/超时:

"Text Viewer Hover Presenter" daemon prio=10 tid=0x00002aad20166400 nid=0x51f4 in Object.wait() [0x000000004254c000..0x000000004254dd90]
   java.lang.Thread.State: WAITING (on object monitor)
    at java.lang.Object.wait(Native Method)
    - waiting on <0x00002aace2276720> (a java.lang.Object)
    at java.lang.Object.wait(Object.java:485)
    at org.eclipse.jdt.internal.ui.javaeditor.ASTProvider.getAST(ASTProvider.java:450)
    - locked <0x00002aace2276720> (a java.lang.Object)
    at org.eclipse.jdt.ui.SharedASTProvider.getAST(SharedASTProvider.java:129)
    at org.eclipse.jdt.internal.ui.text.java.hover.NLSStringHover.getHoverInfo(NLSStringHover.java:87)
    at org.eclipse.jdt.internal.ui.text.java.hover.AbstractJavaEditorTextHover.getHoverInfo2(AbstractJavaEditorTextHover.java:86)
    at org.eclipse.jdt.internal.ui.text.java.hover.BestMatchHover.getHoverInfo2(BestMatchHover.java:129)
    at org.eclipse.jdt.internal.ui.text.java.hover.JavaEditorTextHoverProxy.getHoverInfo2(JavaEditorTextHoverProxy.java:82)
    at org.eclipse.jface.text.TextViewerHoverManager$4.run(TextViewerHoverManager.java:166)

答案 4 :(得分:0)

DiskIndex.java可能没有行信息吗?我的猜测是你在试图获取一个完全不同的锁的方法内部,但是你看不到它,因为堆栈跟踪中没有要显示的行信息。

相关问题