2010-11-28 6 views
2

スレッド1:単純なJava並行処理の問題

if(!conditionFullfiled) this.wait(); 

スレッド2:

if(conditionFullfiled) thread1.notify(); 

私はいくつかの条件がfullfiledされたときに、スレッド2からスレッド1を覚ますしたいです。しかし、thread1.notify()if(!conditionFullfiled) ***HERE*** this.wait();と呼ばれるとき、問題はありませんか?

答えて

3

obj.wait()obj.notify()を行うには、待つ/通知するオブジェクトのモニターを所有する必要があります。あなたのコードでは、おそらくthread1.notify()は必要ありません。例:

Object someSharedObject = ... 

スレッド1:

synchronized(someSharedObject) { 
    // while NOT if for spurious wake ups. 
    while(!conditionFullfiled) someSharedObject.wait(); 
    } 

スレッド2:

synchronized(someSharedObject) { 
    if(conditionFullfiled) someSharedObject.notify(); // this wakes thread1 
    } 

​​ロックは、2つのスレッドが衝突することはありませんを意味し、(thisすることができます)someSharedObjectです。 .wait()は、現在保持されているモニタを解放するため、Thread1が待機しているときにThread2はブロックされません。

編集:私は偽の目覚めについて何かを学んだ。 .wait()whileループで完了する必要があります。ループifでは不十分です。 Why do threads spontaneously awake from wait()?。私に教えてくれてありがとうございました。

編集:明確に.wait()がリリースされました。

+0

http://download.oracle.com/javase/6/docs/api/ を読みます偽の起床に対処する。 –

+0

'someSharedObject.wait();'はsynchronizedブロック内で呼び出されます。つまり、Thread1がすでに待機中であれば、他のsynchronizedブロックに入ることはありませんか? – fhucho

+0

@fhucho、 'wait()'は現在保持しているモニタを解放します。 –

0

"this"として使用するオブジェクトは何ですか?あなたがスレッド1オブジェクト上で()の待機を呼び出し、そしてあなたが示された両方のステートメントは、このようなループに包まれている場合:あなたが望むよう

new Runnable() { 
    synchronized (thread1) { 
     thread1.wait() 
    } 
} 

は、次に、あなたのコードが動作します。 (条件がfalseの場合、最初のスレッドは停止し、それ以外の場合は動作します)。 トリックは、スレッドオブジェクトの対話が同期されているため、他のスレッドがオブジェクトで作業している間にスレッドが中断できないということです。

EDIT: スレッドではなく、他のオブジェクト(単にロックを提供するために純粋なオブジェクトを作成することができます)で同期する方が良いでしょう。

0

待機リリースオブジェクトロック(この場合)。

偽の起床を避けるために、ブロック中の待機/通知条件を守ることがベストプラクティスです。

3

ここには2つの問題があります。

  1. スレッドオブジェクト自体でwait()およびnotify()を呼び出すべきではありません。これを行うより良い方法は、特別なロックオブジェクトを使用することです。

    プライベートオブジェクトlock = new Object(); ......lock.wait();

  2. 次の問題は、両方の待ち(呼び出し)とsynchornizedブロックに通知しなければならないことであり、すなわち

    syncronized(ロック){ //何らかのコード lock.wait()。コード内の他の場所で、その後 }

は言う:

syncronized(lock) { 
    lock.notify(); // this line will cause the wait to terminate and the first thread to continue. 
} 

1つのクラスの両方wait()notify()ラッピング方法をローカライズするために便利であるので、彼らはオブジェクトをロックするためのアクセス権を持っています。詳細については

は `if`が` while`に置き換えてくださいhttp://download.oracle.com/javase/6/docs/api/java/lang/Thread.html

関連する問題