我正在研究的这个java程序似乎在启动时挂起,所以我尝试使用jconsole来调试问题。 事实证明它正在等待对声明为 -
的方法的调用synchronized void stopQuery()
但是这里是疯狂的部分,'同步'方法的锁已经被阻塞的线程所持有。
我在执行getThreadInfo()MXBean方法后附加了JConsole的截图。
请注意,lockOwnerId和threadId是一样的!这怎么可能呢?
编辑:
Link 到这种情况的堆栈跟踪之一。
请注意,在查看堆栈跟踪后,即使'org.eclipse.jdt.internal.ui.text.JavaReconciler'线程也试图锁定到同一个DiskIndex对象,但是如果你查看对象地址,你会看到看到它实际上是一个不同的DiskIndex对象。
编辑2:
Another Link 我在复制此问题时获得的不同堆栈跟踪。将两者进行比较以了解常见情况应该会有所帮助。
答案 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可能没有行信息吗?我的猜测是你在试图获取一个完全不同的锁的方法内部,但是你看不到它,因为堆栈跟踪中没有要显示的行信息。