みんなの「教えて(疑問・質問)」にみんなで「答える」Q&Aコミュニティ

こんにちはゲストさん。会員登録(無料)して質問・回答してみよう!

解決済みの質問

交互にスレッド実行 (どうしてちゃんと動いてる?)

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()} ブロックに入れず待機するはずだと思うのですが。
なぜちゃんと動いているのでしょう?

投稿日時 - 2007-05-02 22:59:05

QNo.2968719

困ってます

質問者が選んだベストアンサー

直接的な回答は、
「obj1.wait();時にはobj1のロックは解除されるので」

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

投稿日時 - 2007-05-03 00:01:39

お礼

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

投稿日時 - 2007-05-08 12:54:10

ANo.1

このQ&Aは役に立ちましたか?

0人が「このQ&Aが役に立った」と投票しています

回答(1)

あなたにオススメの質問