|
JavaTM Platform Standard Ed. 6 |
|||||||||
前のクラス 次のクラス | フレームあり フレームなし | |||||||||
概要: 入れ子 | フィールド | コンストラクタ | メソッド | 詳細: フィールド | コンストラクタ | メソッド |
public interface Condition
Condition
は、Object
監視メソッド (wait
、notify
、および notifyAll
) を別個のオブジェクトに分解し、それらに任意の Lock
実装の使用を組み合わせて、オブジェクトごとに複数の待機セットを保持する効果を付与します。ここで、Lock
は synchronized
メソッドおよび文の使用を置き換え、Condition
は Object 監視メソッドの使用を置き換えます。
状態 (「状態キュー」や「状態変数」とも呼ばれる) は、ある状態が true になったことが別のスレッドにより通知されるまで、スレッドが実行を停止 (待機) する手段を提供します。この共有状態情報へのアクセスは別のスレッド内で行われるため、このアクセスを保護する必要があります。このため、なんらかの形式のロックがこの状態と関連付けられています。状態待機の提供する主要プロパティーは、Object.wait
と同様、関連するロックを「原子的に」解放し、現在のスレッドを停止させることです。
Condition
インスタンスは、内在的にロックにバインドされています。特定の Lock
用の Condition
インスタンスを取得するために、インスタンスは newCondition()
メソッドを使用します。
例として、put
および take
メソッドをサポートするバウンドバッファーを保持する場合を考えましょう。空のバッファーに対して take
が試みられると、項目が利用可能になるまでスレッドがブロックします。いっぱいの状態のバッファーに対して put
が試みられると、空間が利用可能になるまでスレッドがブロックします。バッファー内で項目または空間が利用可能になった時点で単一スレッド通知だけの最適化を使用できるように、put
スレッドと take
スレッドを別個の待機セット内で待機させることにします。これは、2 つの Condition
インスタンスを使用して達成できます。
class BoundedBuffer { final Lock lock = new ReentrantLock(); final Condition notFull = lock.newCondition(); final Condition notEmpty = lock.newCondition(); final Object[] items = new Object[100]; int putptr, takeptr, count; public void put(Object x) throws InterruptedException { lock.lock(); try { while (count == items.length) notFull.await(); items[putptr] = x; if (++putptr == items.length) putptr = 0; ++count; notEmpty.signal(); } finally { lock.unlock(); } } public Object take() throws InterruptedException { lock.lock(); try { while (count == 0) notEmpty.await(); Object x = items[takeptr]; if (++takeptr == items.length) takeptr = 0; --count; notFull.signal(); return x; } finally { lock.unlock(); } } }(この機能は
ArrayBlockingQueue
クラスにより提供されるため、この使用例のクラスを実装する必要はない)
Condition
実装は、通知順序付けが保証されることや、通知の実行時にロックを保持する必要がないことなど、Object
監視メソッドの動作やセマンティクスとは異なる動作やセマンティクスを提供できます。実装がこうした特殊セマンティクスを提供する場合、実装はこれらのセマンティクスをドキュメント化する必要があります。
Condition
インスタンスは通常のオブジェクトであり、それ自体を synchronized
文のターゲットに使用できること、および独自の監視の待機
および通知
メソッドを呼び出せることに留意してください。Condition
インスタンスの監視ロックの取得、またはその監視メソッドの使用は、Condition
に関連付けられた Lock
の取得または待機および信号送信メソッドの使用とは特に関係がありません。混乱を避けるため、独自実装の内部を除き、Condition
インスタンスをこのような方法では決して使用しないようにしてください。
特に明記されていないかぎり、いずれかのパラメータに対し null
値を渡すと、NullPointerException
がスローされます。
Condition
の待機中に、通常、基になるプラットフォームセマンティクスへの譲歩として「見せかけの起動」が許可されます。Condition
はループ上で常に待機して、待機対象の状態予測をテストする必要があるため、これはたいていのアプリケーションプログラムでは実質的な効果はほとんどありません。実装は見せかけの起動の可能性を自由に削除できますが、アプリケーションプログラマはそれが発生し、ループ上で常に待機するものと想定することをお勧めします。
状態待機の 3 つの形式 (割り込み可、割り込み不可、および時刻指定) では、プラットフォームでの実装の容易性およびパフォーマンス特性が異なります。特に、これらの機能を提供しつつ、順序付け保証などの特定のセマンティクスを維持することが困難な場合があります。さらに、実際のスレッド中断に割り込む機能をすべてのプラットフォームで実装することは、常に実行可能であるとは限りません。
従って、実装が、3 つの待機形式すべてで同一の保証やセマンティクスを定義することは要求されていません。 また、実際のスレッド中断に対する割り込みをサポートする必要もありません。
実装は、待機中の各メソッドで提供されるセマンティクスや保証、および実装がスレッド中断の割り込みをサポートし、このインタフェースで定義された割り込みセマンティクスに従う必要がある場合を明確にドキュメント化する必要があります。
通常、割り込みは取り消しを意味し、割り込みのチェックは頻繁に行われるものではないため、実装は通常のメソッド復帰に対する割り込みに肯定的に応答できます。これは、別のアクションがスレッドをブロック解除したあとに、割り込みが発生したことが示される場合にも当てはまります。実装は、この動作をドキュメント化する必要があります。
メソッドの概要 | |
---|---|
void |
await()
信号が送信されるか、割り込みが発生するまで、現在のスレッドを待機させます。 |
boolean |
await(long time,
TimeUnit unit)
信号が送信される、割り込みが発生する、または指定された待機時間が経過するまで、現在のスレッドを待機させます。 |
long |
awaitNanos(long nanosTimeout)
信号が送信される、割り込みが発生する、または指定された待機時間が経過するまで、現在のスレッドを待機させます。 |
void |
awaitUninterruptibly()
現在のスレッドを、信号が送られるまで待機させます。 |
boolean |
awaitUntil(Date deadline)
信号が送信される、割り込みが発生する、または指定された期限が経過するまで、現在のスレッドを待機させます。 |
void |
signal()
待機中のスレッドを 1 つ起動します。 |
void |
signalAll()
待機中のすべてのスレッドを起動します。 |
メソッドの詳細 |
---|
void await() throws InterruptedException
この Condition
に関連付けられているロックは原子的に解放されます。また、現在のスレッドはスレッドのスケジューリングとしては無効になり、次の 4 つのいずれかが起きるまで待機します。
Condition
に対して signal()
メソッドを呼び出し、現在のスレッドが起動スレッドとして選択される。
Condition
に対して signalAll()
メソッドを呼び出す。
いずれの場合でも、このメソッドが現在のスレッドを返す前に、この状態に関連付けられたロックを再取得する必要があります。スレッドの復帰時に、このロックを保持することが保証されます。
現在のスレッドで、
InterruptedException
がスローされ、現在のスレッドの割り込みステータスがクリアされます。初回時には、ロックが解放される前に割り込みのテストが実行されるかどうかは指定されません。
実装上の考慮事項
このメソッドの呼び出し時に、現在のスレッドは、この Condition
に関連付けられているロックを保持するものとみなされます。これが応答方法を決定する要因になるかどうかは、実装によって異なります。通常、(IllegalMonitorStateException
などの) 例外がスローされ、実装はそのことをドキュメント化する必要があります。
実装は、信号に応答して実行される通常のメソッド復帰に対する割り込みに肯定的に応答できます。この場合、実装は、別の待機スレッドが存在する場合に、信号がそのスレッドに確実にリダイレクトされるようにする必要があります。
InterruptedException
- 現在のスレッドで割り込みが発生する (およびスレッド中断の割り込みがサポートされる) 場合void awaitUninterruptibly()
この状態に関連付けられているロックは原子的に解放されます。また、現在のスレッドはスレッドのスケジューリングとしては無効になり、次の 3 つのいずれかが起きるまで待機します。
Condition
に対して signal()
メソッドを呼び出し、現在のスレッドが起動スレッドとして選択される。
Condition
に対して signalAll()
メソッドを呼び出す。
いずれの場合でも、このメソッドが現在のスレッドを返す前に、この状態に関連付けられたロックを再取得する必要があります。スレッドの復帰時に、このロックを保持することが保証されます。
現在のスレッドがこのメソッドに入るときに割り込み状態が設定されるか、待機中に割り込みが発生する場合、信号が送信されるまで待機が継続されます。このメソッドからの最終復帰時にも、「割り込み状態」は引き続き設定されます。
実装上の考慮事項
このメソッドの呼び出し時に、現在のスレッドは、この Condition
に関連付けられているロックを保持するものとみなされます。これが応答方法を決定する要因になるかどうかは、実装によって異なります。通常、(IllegalMonitorStateException
などの) 例外がスローされ、実装はそのことをドキュメント化する必要があります。
long awaitNanos(long nanosTimeout) throws InterruptedException
この状態に関連付けられているロックは原子的に解放されます。また、現在のスレッドはスレッドのスケジューリングとしては無効になり、次の 5 つのいずれかが起きるまで待機します。
Condition
に対して signal()
メソッドを呼び出し、現在のスレッドが起動スレッドとして選択される。
Condition
に対して signalAll()
メソッドを呼び出す。
いずれの場合でも、このメソッドが現在のスレッドを返す前に、この状態に関連付けられたロックを再取得する必要があります。スレッドの復帰時に、このロックを保持することが保証されます。
現在のスレッドで、
InterruptedException
がスローされ、現在のスレッドの割り込みステータスがクリアされます。初回時には、ロックが解放される前に割り込みのテストが実行されるかどうかは指定されません。
このメソッドは、復帰時に、指定された待機時間を示す nanosTimeout
値に対する残りの推定ナノ秒数を返します。タイムアウト時間が経過している場合は、ゼロまたはゼロ未満の値を返します。待機が復帰しても待機状態が依然として保持されない場合に、この値を使用して、再度待機するかどうか、およびその期間を決定できます。通常、このメソッドは次の形式になります。
synchronized boolean aMethod(long timeout, TimeUnit unit) { long nanosTimeout = unit.toNanos(timeout); while (!conditionBeingWaitedFor) { if (nanosTimeout > 0) nanosTimeout = theCondition.awaitNanos(nanosTimeout); else return false; } // ... }
設計上の注意:このメソッドは、残り時間をレポートする際に切り詰めエラーの発生を避けるためにナノ秒の引数を指定する必要があります。この精度が低下すると、待機時間の合計が、指定された再待機の発生時よりもシステム的に短くないことをプログラマが保証することが難しくなります。
実装上の考慮事項
このメソッドの呼び出し時に、現在のスレッドは、この Condition
に関連付けられているロックを保持するものとみなされます。これが応答方法を決定する要因になるかどうかは、実装によって異なります。通常、(IllegalMonitorStateException
などの) 例外がスローされ、実装はそのことをドキュメント化する必要があります。
実装は、信号に応答して実行される通常のメソッド復帰に対する割り込み、または指定された待機時間の経過指示に対する割り込みに肯定的に応答できます。どちらの場合も、実装は、別の待機スレッドが存在する場合に、信号がそのスレッドに確実にリダイレクトされるようにする必要があります。
nanosTimeout
- ナノ秒単位の待機時間
nanosTimeout
値から引いた推定数。
正の値は、希望する時間だけ待機できるように、このメソッドの以後の呼び出しに対する引数として使用される。ゼロ以下の値は、時間が残っていないことを示す
InterruptedException
- 現在のスレッドで割り込みが発生する (およびスレッド中断の割り込みがサポートされる) 場合boolean await(long time, TimeUnit unit) throws InterruptedException
awaitNanos(unit.toNanos(time)) > 0
time
- 待機する最長時間unit
- time
引数の時間単位
false
、そうでない場合は true
InterruptedException
- 現在のスレッドで割り込みが発生する (およびスレッド中断の割り込みがサポートされる) 場合boolean awaitUntil(Date deadline) throws InterruptedException
この状態に関連付けられているロックは原子的に解放されます。また、現在のスレッドはスレッドのスケジューリングとしては無効になり、次の 5 つのいずれかが起きるまで待機します。
Condition
に対して signal()
メソッドを呼び出し、現在のスレッドが起動スレッドとして選択される。
Condition
に対して signalAll()
メソッドを呼び出す。
いずれの場合でも、このメソッドが現在のスレッドを返す前に、この状態に関連付けられたロックを再取得する必要があります。スレッドの復帰時に、このロックを保持することが保証されます。
現在のスレッドで、
InterruptedException
がスローされ、現在のスレッドの割り込みステータスがクリアされます。初回時には、ロックが解放される前に割り込みのテストが実行されるかどうかは指定されません。
戻り値は、期限が経過したかどうかを示します。この値は次のように使用できます。
synchronized boolean aMethod(Date deadline) { boolean stillWaiting = true; while (!conditionBeingWaitedFor) { if (stillWaiting) stillWaiting = theCondition.awaitUntil(deadline); else return false; } // ... }
実装上の考慮事項
このメソッドの呼び出し時に、現在のスレッドは、この Condition
に関連付けられているロックを保持するものとみなされます。これが応答方法を決定する要因になるかどうかは、実装によって異なります。通常、(IllegalMonitorStateException
などの) 例外がスローされ、実装はそのことをドキュメント化する必要があります。
実装は、信号に応答して実行される通常のメソッド復帰に対する割り込み、または指定された期限の経過指示に対する割り込みに肯定的に応答できます。どちらの場合も、実装は、別の待機スレッドが存在する場合に、信号がそのスレッドに確実にリダイレクトされるようにする必要があります。
deadline
- 待機する絶対時間
false
、そうでない場合は true
InterruptedException
- 現在のスレッドで割り込みが発生する (およびスレッド中断の割り込みがサポートされる) 場合void signal()
この状態で待機中のスレッドが存在する場合、1 つのスレッドが起動用に選択されます。このスレッドは、await
から復帰する前にロックを再取得する必要があります。
void signalAll()
この状態で待機中のスレッドが存在する場合、すべてのスレッドが起動されます。各スレッドは、await
から復帰する前にロックを再取得する必要があります。
|
JavaTM Platform Standard Ed. 6 |
|||||||||
前のクラス 次のクラス | フレームあり フレームなし | |||||||||
概要: 入れ子 | フィールド | コンストラクタ | メソッド | 詳細: フィールド | コンストラクタ | メソッド |
Copyright 2006 Sun Microsystems, Inc. All rights reserved. Use is subject to license terms. Documentation Redistribution Policy も参照してください。