4

2つのメソッドでsynchronize(this)を使用し、一方が他方を呼び出す場合、デッドロック状態でスタックしますか、それともスレッドがすでにロックを所有しているために機能しますか?

以下のクラスを想像してください。

public class Test {
  public void foo() {
    synchronize(this) {
      bar();
    }
  }

  public void bar() {
    synchronize(this) {
      // do something
    }
  }
}

ご覧のとおり、fooとbarの2つのメソッドがあり、どちらも同期に依存しています。

foo()を呼び出すと、(this)でロックが取得されます。barはfooによって呼び出されたときに同じことを行おうとしますか(したがってデッドロックを引き起こします)、またはロックが同じスレッドによってすでに取得されていることを認識しますか?

私の説明が多かれ少なかれ明確であることを願っています;-)

4

3 に答える 3

10

ブロックは再入可能であるsynchronizedため(実際、Javaモニターは再入可能であり、完全に明確になります)、状況によってデッドロックが発生することはありません。

ドキュメントによると:

スレッドが別のスレッドが所有するロックを取得できないことを思い出してください。ただし、スレッドはすでに所有しているロックを取得できます。

于 2012-06-25T17:13:31.807 に答える
3

スレッドがオブジェクトのロックを保持している場合、そのロックオブジェクトに基づいて他の同期ブロックに入ることができます。

ここであなたはそれを読むことができます

「...スレッドはすでに所有しているロックを取得できます。スレッドが同じロックを複数回取得できるようにすると、再入可能同期が有効になります。これは、同期コードが直接または間接的に、同期コードも含むメソッドを呼び出す状況を示しています。両方のコードセットが同じロックを使用します。再入可能な同期がない場合、同期されたコードは、スレッドがそれ自体をブロックしないようにするために、多くの追加の予防措置を講じる必要があります。」

于 2012-06-25T17:14:58.370 に答える
0

ただし、注意すべきことの1つは、次の場合です。

Thread A has the lock in foo() and needs to call bar()

and Thread B has the lock in bar() while needing to call foo()
于 2012-06-25T17:22:49.797 に答える