7

Java仮想マシンの仕様とコンパイルされたコードを見ると、「同期された」ブロックがJavaでどのように実装されているかがわかります。次のコード:

public void testSync()
{
    Object obj = getSomeObject();
    synchronized (obj) { doSomething(); }
}

...この擬似コードとほぼ同等です。

public void testSync()
{
    Object obj = getSomeObject();
    Object __temp = obj;
    monitorenter __temp;
    try { doSomething(); }
    finally { monitorexit __temp; }
}

...1つの例外を除いて。

何らかの理由で、例外テーブルには2つのfinallyハンドラーが表示されます。例えば:

  Exception table:
     from    to  target type
        12    20    23   any
        23    25    23   any

最初のハンドラーは私が期待する場所ですが、2番目のハンドラーは実際には最初のハンドラーのfinallyブロック用であり、例外をキャッチすると同じハンドラーを実行します。次の方法では、これをうまく視覚化できません。

try { doSomething(); }
finally { beginTry: try { monitorexit __temp; } finally { goto beginTry; } }

なぜこれなのか誰か知っていますか?それがfinallyブロックだけの場合、テーブルの2番目のエントリはそこにありません。その上、すでに例外がスローされている場合、finallyブロックを再度実行したい理由はわかりません。

ありがとう、ブランドン

4

1 に答える 1

2

モニターを解放するために何度も試行するか、解放せずに続行するかの選択である場合、両方の方法でデッドロックが発生します。リリースせずに続行した場合、次に何かがモニターを取得しようとするまでデッドロックは発生せず、その問題は最初の障害から遠く離れている可能性があります。また、モニターを解放しようとすると、最終的にはうまくいく可能性がありますが、モニターを解放しないままにしておくことは特定の災害です。したがって、再試行することをお勧めします。

于 2013-02-27T20:26:03.923 に答える