• 締切済み

デッドロック回避のためのwait() notify()

学生です。最近javaの勉強をはじめました。 synchronized statementでデットロック回避のためにwait() notify()の使い方がよくわかりません。本にはwait()はスレッドがsynchronizedで獲得してあるロックを解放し、待機状態に入るとのことを書いてありましたが、なぜ、wait()をwhileループでまわすのでしょうか? それと、notifyは待機状態のスレッドに対して通知し、通知されたスレッドは待機状態から実行状態に移るとのことですが、whileループで再びwait()を実行し永遠に抜け出せないと思うのですがどうなんでしょうか? お手数ですが、詳しい方がいらしたら教えていただけないでしょうかお願いします。

みんなの回答

  • akr
  • ベストアンサー率18% (32/173)
回答No.2

evenThreadActionメソッドとoddThreadActionメソッドのc0及びc1が同じオブジェクトを参照するとデッドロック状態になるという認識でよろしいでしょうか? ちなみに、スレッドのスィッチングは、Thread.sleep(2)の所でしか行われないと言う前提でしょうか?タスクの切替は、VMの仕様としては定義されていません。スィッチングのタイミングは、実装に依存(通常はOS任せ)です。よって、環境によっては、上記したsleepでしか切り替わりませんが、別の環境ではタイムスライス動くかもしれません。 waitとnotifyを何処で使えばデッドロックの回避が出来るかって事ですが、上記の状態にならなければ良いのですから、いずれかのスレッドが、c0を取得した時に、他のスレッドをwaitして、synchronizedを抜けたところで、notify(またはnotiflAll)すれば良さげですが...これだとマルチスレッドの意味無しですね。さらに他のスレッドに対してwaitしようと思ったら、他のスレッドの参照が出来る必要が出てきますね。なんか別の方法がありそうな気がしますが思いつきません。 あまり力になれなかったようで申し訳無い

  • akr
  • ベストアンサー率18% (32/173)
回答No.1

synchronizedでデッドロック回避と言っても何に対するデッドロックなんでしょか?文面を見る限り、何かソースを見ての疑問のように見うけられますが、そのソースが無いので、なんとも言えません。抜粋でかまいませんのでソースを載せて頂けませんか。

kanep
質問者

お礼

for(int i = 0 ; i < threadNumber ; i++) new BubbleSort(i, array, mc, latch).start() ; //////////////////// class BubbleSort extends Thread { private int number ; private Array array ; private MyCanvas mc ; private Latch latch ; BubbleSort(int n, Array a, MyCanvas m, Latch l) { number = n ; array = a ; mc = m ; latch = l ; } public void run() { try{ latch.acquire() ; if(number % 2 == 0) evenThreadAction() ; else oddThreadAction() ; System.out.println("****** Completed Thread No." + number) ; } catch(InterruptedException e){ } } private void evenThreadAction() { boolean complete = false ; while(!complete){ boolean changed = false ; for(int i = 0 ; i < array.getSize() - 1 ; i++){ Cell c0 = array.getCell(i) ; synchronized(c0){ Cell c1 = array.getCell(i + 1) ; synchronized(c1){ if(c0.getValue() > c1.getValue()){ c0.swapValue(c1) ; changed = true ; mc.repaint() ; try{Thread.sleep(2);}catch(InterruptedException e){} } } } } if(!changed) complete = true ; } } private void oddThreadAction() { boolean complete = false ; while(!complete){ boolean changed = false ; for(int i = array.getSize() - 1 ; i > 0 ; i--){ Cell c0 = array.getCell(i-1) ; synchronized(c0){ Cell c1 = array.getCell(i) ; synchronized(c1){ if(c0.getValue() > c1.getValue()){ c0.swapValue(c1) ; changed = true ; mc.repaint() ; try{Thread.sleep(2);}catch(InterruptedException e){} } } } } if(!changed) complete = true ; } } } 上のソースはプログラムのスレッドの処理の部分です。 プログラムの内容はバブルソートアルゴリズムを複数のスレッドを使って行った場合、生成順が奇数のスレッドと偶数のスレッドでアクションが逆なので処理を繰り返していくうちに典型的なデッドロックの状態になるということです。アルゴリズムを変えればデッドロックは回避できますが、そうではなくwait() notify()を使った回避方法を知りたいです。よろしくお願い致します。

kanep
質問者

補足

わざわざありがとうございます。 実はこれは授業の課題なのですが、ソースは研究室のPCにあり、 今、家に帰ってしまったため、載せることができません。 明日になってしまいますが、ソースを載せますのでお手数ですがよろしくお願い致します。