while ループを持つメイン スレッドがあり、この中で彼はいくつかの条件をチェックし、すべての条件が満たされた場合、別のスレッドを開始して wait() 状態に入ります。
並行して実行される他のスレッドは、作業の完了時にメイン スレッドに通知します。
メインスレッドが待ち状態=デッドロックに入る前に「サブスレッド」がメインスレッドに通知すると問題が発生します。
それを避けるためのベストプラクティスは何ですか?
while ループを持つメイン スレッドがあり、この中で彼はいくつかの条件をチェックし、すべての条件が満たされた場合、別のスレッドを開始して wait() 状態に入ります。
並行して実行される他のスレッドは、作業の完了時にメイン スレッドに通知します。
メインスレッドが待ち状態=デッドロックに入る前に「サブスレッド」がメインスレッドに通知すると問題が発生します。
それを避けるためのベストプラクティスは何ですか?
通知にはセマフォを使用します。
それだけです、本当に。セマフォにはカウントがあり、メインスレッドが待機するまで通知を記録できます。
簡単な答えは、Java 5 の同時実行パッケージを使用することです。ここでは、CountDownLatch が適しているようです。
Java 5 より前の環境に制限されている場合は、同じアルゴリズムを使用するカスタム実装を作成する必要があります。メイン スレッドは、すべての子スレッドの作成後に signalReady を呼び出します。子スレッドは、作業の完了後に signalComplete を呼び出します。
簡単な実装は、2 つの 2 つのメンバー フィールドを持つ Latch と呼ばれるオブジェクトを持つことです。
以下の実装は、1 つの親と 1 つの子に対して機能します。追加の子については、各子に独自のラッチを与えて、完了時に通知することができます。これが競合状態になるケースがまだあります。シグナリングの間にスピンロックまたはスリープを追加すると、競合状態の可能性が減少します。それはそれを排除しません
class Latch{
Object readyLock;
Object completeLock;
public void signalComplete(){
synchronized(readyLock){
readyLock.wait()
}
//spin lock as a precaution
synchronized(completeLock){
completeLock.notify()
}
}
public void signalReady(){
synchronized(readyLock){
readyLock.notify()
}
synchronized(completeLock){
completeLock.wait()
}
}
}
お役に立てれば!
Explicit Locksを使用したいと思います。Java 並行 API を参照してください。
http://docs.oracle.com/javase/1.5.0/docs/api/java/util/concurrent/locks/Lock.html