2016-07-17 29 views
1

私は、put()でスレッドによって設定されているBlockingQueueを持っています。しかし、私はBlockingQueueのtake()のやり方について混乱しています。現在、私はこの方法で実装しています:Java BlockingQueue while()whileループ

String link; 
try { 
    while(!(link = links.take()).isEmpty()) { 
     System.out.println(link); 
    } 
} catch(InterruptedException ex) { 
    ex.printStackTrace(); 
} 

そうですか?どのようにキューをループし、条件文の中になければ文字列変数を割り当てることが可能ですか?

答えて

1

私が正しく理解していれば、条件外の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の一部です。

+0

しかし、特定の数の要素が消費者によって処理された後、生産を停止する時期を生産者コード内で知ることは可能でしょうか? – davidchoo12

+0

これは非同期で実行できます。 'n'個のアイテムを消費させたいとしましょう。次に、' n'の容量を持つ 'ArrayBlockingQueue'を作成することができます。 'put'は、キューに十分なスペースがない場合にのみブロックするので、プロデューサーは発火して忘れることができます。 – beatngu13

+0

しかし、消費者から「テイク」するとスペースが作られ、プロデューサーはキューに入れ続けるので、プロデューサーを一時停止するだけですが、消費者が一度多くのアイテムを処理すると完全に停止します。 – davidchoo12

0

BlockingQueueを正常に終了させる方法について質問しています。私が考えることができる2つのシナリオがあります。いずれにしても、メッセージプロデューサAとメッセージコンシューマBがあります。

  1. メッセージプロデューサは、「停止」のような端末の値を送信します。あなたはそれをチェックし、whileのサイクルは終了します。
  2. コンシューマ側でInterruptedExceptionをスローするメッセージプロデューサを中断できます。これは、端末入力の場合を回避する方法です。ここでの問題は、コンシューマがキューにあるすべてのものを実際に消費しているかどうかを制御できないことです。したがって、通常は、消費を即座に終了する必要のある条件がある場合は、割り込みが使用されます。