私が正しく理解していれば、条件外のtake
への道を尋ねましたか?まあ、それはそんなに難しいことではありません。
while (!links.isEmpty()) {
try {
String link = links.take();
// Do stuff.
} catch (InterruptedException e) {
// Exception handling.
}
}
あなたの現在の状態!(link = links.take()).isEmpty()
チェック空の戻り値-ある文字列(長さが0に等しい)、ないキュー場合。
上記コードはatomicではありませんので、links.isEmpty()
とlinks.take()
の間に何も起こらないことを保証するものではありません。
EDIT:
BlockingQueue<Integer> numbers = new ArrayBlockingQueue<>(10);
AtomicBoolean flag = new AtomicBoolean(true);
// Producer.
new Thread(() -> {
for (int i = 0; i < 10; i++) {
try {
numbers.put(i);
} catch (InterruptedException e) { /* NOP */ }
}
flag.set(false);
}).start();
// Consumer.
while (flag.get() || !numbers.isEmpty()) {
try {
System.out.println(numbers.take());
} catch (InterruptedException e) { /* NOP */ }
}
AtomicBoolean
はここでは必要ありませんが、複数の生産者および/または消費者を持っている場合、それは便利になるかもしれません:あなたはフラグを起動時にrace conditionsを扱うことができます。また、それはあなたが間違いなくチェックアウトしなければならないjava.util.concurrent
の一部です。
しかし、特定の数の要素が消費者によって処理された後、生産を停止する時期を生産者コード内で知ることは可能でしょうか? – davidchoo12
これは非同期で実行できます。 'n'個のアイテムを消費させたいとしましょう。次に、' n'の容量を持つ 'ArrayBlockingQueue'を作成することができます。 'put'は、キューに十分なスペースがない場合にのみブロックするので、プロデューサーは発火して忘れることができます。 – beatngu13
しかし、消費者から「テイク」するとスペースが作られ、プロデューサーはキューに入れ続けるので、プロデューサーを一時停止するだけですが、消費者が一度多くのアイテムを処理すると完全に停止します。 – davidchoo12