4

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

synchronized void stopQuery()

但这是疯狂的部分,“同步”方法的锁已经被为它阻塞的线程持有。在执行 getThreadInfo() MXBean 方法后,我附上了 JConsole 的屏幕截图。

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

替代文字

编辑:
链接到这种情况的堆栈跟踪之一。请注意,在查看堆栈跟踪后,可能会出现甚至 'org.eclipse.jdt.internal.ui.text.JavaReconciler' 线程正在尝试锁定同一个 DiskIndex 对象,但如果您查看对象地址,您将看到它实际上是一个不同的 DiskIndex 对象。

编辑 2: 我在重现此问题时获得的
另一个指向不同堆栈跟踪的链接。将两者进行比较以了解共同点应该会有所帮助。

4

5 回答 5

2

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

“Text Viewer Hover Presenter”和“Worker-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)
于 2008-12-03T18:27:48.007 回答
0

不知何故,该方法是递归的吗?也许您在其中使用了一个需要相同方法的对象?

于 2008-12-03T10:02:59.243 回答
0

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

于 2008-12-03T10:04:37.757 回答
0

可能值得尝试死锁检测代码位 -像这样

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)
于 2008-12-03T10:52:11.670 回答
0

DiskIndex.java 是否可能没有行信息?我的猜测是,您正在尝试获取完全不同的锁的方法中,但您看不到,因为堆栈跟踪中没有要显示的行信息。

于 2008-12-03T10:55:53.393 回答