人に聞けない痔の悩み、これでスッキリ >>

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で質問しましょう!

このQ&Aを見た人はこんなQ&Aも見ています

このQ&Aを見た人が検索しているワード

このQ&Aと関連する良く見られている質問

Qスレッド1とスレッド2を交互に実行するには?

スレッド1→スレッド2→スレッド1・・・と同期を取り合いながら交互にスレッドを動かしたいのですが、Thread.getState()を用いないで実現するよい方法はないでしょうか?
どうしてもデッドロックが発生しうる方法しか思いつかず困っています。
例えば以下のプログラムで1212と交互に表示させたい場合です。
以下のプログラムは当然デッドロックになりますが、やりたいことを伝えるために載せておきます。

Object obj; //スレッド間通信用のobject

class Test1 extends Thread {
 public void run() {
  while(true) {
   System.out.print("1");
   synchronized (obj) {
    obj.notify();//相手をnotifyして
    obj.wait();//自分はwait
   }
  }
 }
}

class Test2 extends Thread {
 public void run() {
  while(true) {
   System.out.print("2");
   synchronized (obj) {
    obj.notify();
    obj.wait();
   }
  }
 }
}
new Test1().start();
new Test2().start();

スレッド1→スレッド2→スレッド1・・・と同期を取り合いながら交互にスレッドを動かしたいのですが、Thread.getState()を用いないで実現するよい方法はないでしょうか?
どうしてもデッドロックが発生しうる方法しか思いつかず困っています。
例えば以下のプログラムで1212と交互に表示させたい場合です。
以下のプログラムは当然デッドロックになりますが、やりたいことを伝えるために載せておきます。

Object obj; //スレッド間通信用のobject

class Test1 extends Thread {
 public void run() {
...続きを読む

Aベストアンサー

スレッド1・2を監視するスレッド3を作って3が1・2を交互に呼ぶ  じゃだめ?


このQ&Aを見た人がよく見るQ&A

人気Q&Aランキング