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

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

締切り済みの質問

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

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

投稿日時 - 2001-07-27 18:42:49

QNo.110274

困ってます

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

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

回答(2)

ANo.2

akr

evenThreadActionメソッドとoddThreadActionメソッドのc0及びc1が同じオブジェクトを参照するとデッドロック状態になるという認識でよろしいでしょうか?
ちなみに、スレッドのスィッチングは、Thread.sleep(2)の所でしか行われないと言う前提でしょうか?タスクの切替は、VMの仕様としては定義されていません。スィッチングのタイミングは、実装に依存(通常はOS任せ)です。よって、環境によっては、上記したsleepでしか切り替わりませんが、別の環境ではタイムスライス動くかもしれません。

waitとnotifyを何処で使えばデッドロックの回避が出来るかって事ですが、上記の状態にならなければ良いのですから、いずれかのスレッドが、c0を取得した時に、他のスレッドをwaitして、synchronizedを抜けたところで、notify(またはnotiflAll)すれば良さげですが...これだとマルチスレッドの意味無しですね。さらに他のスレッドに対してwaitしようと思ったら、他のスレッドの参照が出来る必要が出てきますね。なんか別の方法がありそうな気がしますが思いつきません。

あまり力になれなかったようで申し訳無い

投稿日時 - 2001-07-30 13:00:44

ANo.1

akr

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

投稿日時 - 2001-07-28 00:10:22

補足

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

投稿日時 - 2001-07-28 00:38:00

お礼

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()を使った回避方法を知りたいです。よろしくお願い致します。

投稿日時 - 2001-07-28 16:31:08

あなたにオススメの質問