take()
どのように機能し、キューにプッシュされた「高速」要素を消費するのに適した方法であるかどうかを理解したいと思います。
それがどのように機能するかを理解するために、ここではオブザーバーパターンを考慮していないことに注意してください。そのパターンを使用してイベントに「迅速に反応」できることは知っていますが、それは私の質問の目的ではありません.
たとえば、BlockingQueue
(ほとんどが空の) スレッドがあり、要素がそのキューにプッシュされて消費されるのを待っているスレッドが「スタック」している場合、その間に費やされる時間を最小限に抑える (レイテンシを減らす) 良い方法は何でしょうか?要素がキューにプッシュされた瞬間とそれが消費された瞬間?
たとえば、これを行うスレッドの違いは何ですか:
while( true ) {
elem = queue.peek();
if ( elem == null ) {
Thread.sleep( 25 ); // prevents busy-looping
} else {
... // do something here
}
}
そして、これを行う別の人:
while ( true ) {
elem = queue.take();
... // do something with elem here
}
(単純化するために、ここで例外について議論することは無視できると思います!?)
電話をかけたときにtake()
キューが空になったとき、内部では何が行われているのでしょうか? JVM は、キューに何かがあるかどうかを常にチェックするビジー ループを行うことができないため、内部でスレッドを「スリープ」する必要がありますか? take()は内部で CAS 操作を使用していますか? もしそうなら、take()がその CAS 操作を呼び出す頻度を決定するものは何ですか?
何かが突然キューに入れられたらどうしますか? そのスレッドは、take()
どうにかしてブロックされ、すぐに行動する必要があることを「通知」されますか?
最後に、アプリケーションの存続期間中、BlockingQueue のtake()で1 つのスレッドが「スタック」するのは「一般的」ですか?
これはすべて、ブロッキングtake()がどのように機能するかに関する 1 つの大きな疑問であり、さまざまな質問 (少なくとも意味のある質問) に答えることが、これらすべてをよりよく理解するのに役立つと思います。