デッドロックについて java

現状のコードではデッドロックは発生しません。

Test.execute はこのコード内ではスレッド2つがそれぞれ1つずつ別のTestインスタンスを占有する形になっているので特に競合は発生しません。
現状に限れば synchronized が付いていても付いていなくても同じ挙動になります。

残りの問題 Sample の各メソッドについてですが
executeに含まれるforループ内からの呼び出しを、次のようなモデルで説明できます。

  • 2つのスレッド t1,t2 がそれぞれリソース s1,s2 を取り合う
  • 各スレッドは s1->s2 の順にリソースを占有し、両方を占有できたら s2->s1 の順で解放する
  • 片方のスレッドがリソースを占有したら、もう片方は解放を待たねばならない

…なんですが、実はこれはもっとシンプルなモデルで説明ができてしまいます。

  • 2つのスレッド t1,t2 がリソース s1 を取り合う
  • 先に s1 を占有した方が、s2占有 -> s2解放 -> s1解放 を行う
  • 片方のスレッドがリソースs1を占有したら、もう片方は解放を待つ

つまり2つのリソースを扱っていますが、実はスレッドのブロックに関わるのは実質1つのリソースだけであり
デッドロック発生の原因である「2つ以上のリソースが必要な処理で、別々のスレッドがそれぞれ別のリソースを占有したままお互いの解放を待つ」という状況が発生し得ません。


わざとデッドロックを起こしたければ、ループ状の配置となるように

java

1 new Thread(() -> {2 t1.execute(s1, s2);3 }).start();4 5 new Thread(() -> {6 t2.execute(s2, s1); //引数の順番入れ替え7 }).start();

などと変更するとよいです

コメントを投稿

0 コメント