4

私が取り組んでいるこのJavaプログラムは、起動時にハングしているように見えるので、jconsoleを使用して問題をデバッグしてみました。結局のところ、次のように宣言されているメソッドへの呼び出しを待機しています-

synchronized void stopQuery()

しかし、ここにクレイジーな部分があります。「同期」メソッドのロックは、ブロックされているスレッドによって既に保持されています。getThreadInfo() MXBean メソッドを実行した後の JConsole のスクリーンショットを添付しました。

lockOwnerId と threadId が同じであることに注意してください。これはどのように可能ですか?

代替テキスト

編集: この状況のスタック トレースの 1 つに
リンクします。スタックトレースを見ると、「org.eclipse.jdt.internal.ui.text.JavaReconciler」スレッドでさえ同じ DiskIndex オブジェクトにロックしようとしているように見えるかもしれませんが、オブジェクトのアドレスを見ると、実際には別の DiskIndex オブジェクトであることがわかります。

編集 2: この問題を再現したときに取得した別のスタック トレースへの
別のリンク。両者を比較して共通点を確認するとよいでしょう。

4

5 に答える 5

2

これは特に厄介なデッドロックのように見えます。もう少し情報がないと確実に言うのは難しいです。ただし、目の前にコードがない場合は次のようになります。

"Worker-3" が参照 0x00002aace2276ad0 のロックを保持している間に、"Text Viewer Hover Presenter" と "Worker-3" の間のオブジェクト参照 0x00002aace2276720 でデッドロック (または少なくとも競合) が発生する可能性があります。

この 2 番目の参照は、ブロックされたスレッド (具体的には「Worker-4」、「Worker-1」、および「Worker-0」) の山全体の原因のようです。

私の提案は、ASTProvider.java の 450 行目を確認することです (疑わしいオブジェクト ロックが保持されているように見えるが、wait() を通過していないように見える最初の 2 つのスタック トレースを参照してください)。シングル コアにロックされた実行可能ファイルを実行することもお勧めします (これがマルチコア システムであると仮定します)。

テストする価値があると思われる次のコードは、SelectionListenerWithASTManager.java の 153 行目です (参照 0x00002aace2276ad0 がロックされているため、ワーカーがブロックされます)。

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

DiskIndex.java に行情報がない可能性はありますか? 私の推測では、まったく別のロックを取得しようとするメソッド内でぶら下がっているのですが、スタック トレースに表示する行情報がないため、それを確認できません。

于 2008-12-03T10:55:53.393 に答える
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 に答える