アプリ版:「スタンプのみでお礼する」機能のリリースについて

http://oshiete1.goo.ne.jp/qa2968378.html
で質問した者です。
2つのスレッドで1と2を交互に実行する以下のプログラム。


final Object obj1 = new Object(); //スレッド間通信用のobject
final Object obj2 = new Object(); //スレッド間通信用のobject2

Thread t1 = new Thread() {
 public void run() {
  try {
   while(true) {
    System.out.print("1");
    synchronized (obj1) {
     synchronized (obj2) {
      obj2.notify();//相手をnotifyして
     }
     obj1.wait();//自分はwait
    }
   }
  } catech (Exception e){}
};

Thread t2 = new Thread() {
 public void run() {
  try {
   while(true) {
    System.out.print("2");
    synchronized (obj2) {
     synchronized (obj1) {
      obj1.notify();
     }
     obj2.wait();
    }
   }
  } catch (Exception e){}
 }
};

Thread t1 = new Test1();
Thread t2 = new Test2();

t1.start();
while(t1.getState() != Thread.State.WAITING);
t2.start();


が思ったように動いてはいるものの、なぜ正常に動いているかがわかりません。
t1が wait() したときはobj1のロックをもっていて、t2の
synchronized (obj1){obj1.notify()} ブロックに入れず待機するはずだと思うのですが。
なぜちゃんと動いているのでしょう?

A 回答 (1件)

直接的な回答は、


「obj1.wait();時にはobj1のロックは解除されるので」

また、そのコードだと、
1. Test1:synchronized (obj1) Test2:synchronized (obj2)
2. Test1:synchronized (obj2) Test2:synchronized (obj1)
の順に動作した場合にデッドロックを起こす可能性が残っていると思います(再現性が落ちただけ)
多分、volatileな状態を組み合わせるなどしないと回避できないと思います。
# なぜ、スレッド構成での直列化にこだわっているのかの背景を知らない身からすると、
# 無駄に大変な努力をすることになるように感じますので、
# 個人的には、前回スレの回答者のご意見を推奨しておきます。
    • good
    • 0
この回答へのお礼

お返事遅れて申し訳ありません。
監視スレッドを使いたくなかった理由は、監視スレッドでwhile()を回すと余計に資源を食いそうだった点と、単に2つでそのようなことが出来るか知りたかった点です。
上記の方法でもデッドロックが生じる可能性があることも承知致しました。
またよろしくお願いします。

お礼日時:2007/05/08 12:54

お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!