0

ブロッキング関数(Java同期メソッド)へのすべての可能な呼び出しを象徴するグラフを描画し、このグラフにサイクルがない場合、デッドロックが不可能であることを確認できますか?ペトリネットはそのようには機能しませんか?

私はこのような答えを探していません:いくつかのモンスターフレームワークを使用してください。

同期されたメソッドでマルチスレッドを処理したい。

EDIT1:先のとがった矢印は、あるクラスが別のクラスの同期メソッドを呼び出すかどうかを示していますEDIT2:klick @here例、サイクルを示しています

4

3 に答える 3

2

いいえ、それだけでは不十分です。AとBのスレッドを作成する必要があるとします。Aはオブジェクトo1のメソッドm1を呼び出し、オブジェクトo2のメソッドm1を呼び出します。スレッドBは、オブジェクトo1のメソッドm2を呼び出すオブジェクトo2のメソッドm2を呼び出します。すべてのメソッドが同期されていると仮定します。現在、デッドロックにつながるAとBの同時実行があります。ただし、メソッド間に循環呼び出し関係はありません。

それは宿題ですか?

クラスに関する編集を行っても、同期されていないメソッド呼び出しを介してサイクルを閉じることができるため、それだけでは不十分です。

于 2011-04-01T10:27:09.120 に答える
0

synchronized一部のメソッドは、キーワードなしでブロックする場合があります。これは、たとえばパッケージ内の多くのメソッドに当てはまりjava.util.concurrentます。synchronizedメソッド内のブロックも考慮する必要があります。

同期されたメソッドのみを検討する場合、同期されたメソッドはオブジェクトインスタンスをモニターとして使用するため、メソッド呼び出しでサイクルなしでデッドロックが発生する可能性があります。たとえば、2つのオブジェクトAとBがあり、それぞれが同期されたメソッド1()と2()を持っているとします。A.1()がB.1()を呼び出し、B.2()がA.2()を呼び出す場合、メソッドにサイクルはありませんが、スレッドがB.2()同時に他の呼び出しA.1()を呼び出すと、デッドロックのリスクがあります。

于 2011-04-01T09:44:06.407 に答える
0

いいえ。考慮してください:

private static final Semaphore foo = new Semaphore(1);
private static final Semaphore bar = new Semaphore(1);

private static void one() throws InterruptedException {
    foo.acquire();
    bar.acquire();
    bar.release();
    foo.release();
}

private static void two() throws InterruptedException {
    bar.acquire();
    foo.acquire();
    foo.release();
    bar.release();
}

実行可能な例については、 http://pastebin.com/QfK5ZByjを参照してください。それは私にとってかなり早くデッドロックします。

于 2011-04-01T10:27:51.787 に答える