2016-08-18 4 views
0

私は、ExecutorServiceを使用して小さなプロデューサ/コンシューマのサンプルをJavaで実装しようとしています。ここでExecutorService.submitを使用しているコンシューマが終了しない

class Example { 
    public static void main(String args[]) { 
     BlockingQueue<String> queue = new ArrayBlockingQueue<>(1000); 
    Producer producer = new Producer(queue); 
    Consumer consumer = new Consumer(queue); 
    ExecutorService executor = Executors.newCachedThreadPool(); 
// executor.execute(consumer); 
    Future producerFuture = executor.submit(producer); 
    Future consumerFuture = executor.submit(consumer); 
    try { 
     producerFuture.get(); 
     consumerFuture.get(); 
    } catch (InterruptedException e) { 
     LOG.error("Failed"); 
    } 
    executor.shutdown(); 
    executor.awaitTermination(10, TimeUnit.MILLISECONDS); 
    } 
} 

プロデューサークラス

public class Producer implements Runnable { 
    private BlockingQueue<String> queue; 
    public Producer(BlockingQueue<String> queue) { 
    this.queue = queue; 
    } 

    @Override 
    public void run() { 
    for (int i = 0; i < 10; i++) { 
     try { 
     queue.put(i + "HELPPPPP"); 
     } catch (InterruptedException ex) { 
     Logger.getLogger(MigrationToolProducer.class.getName()).log(Level.SEVERE, null, ex); 
     } 
    } 

コンシューマークラス

public class Consumer implements Runnable { 
    private final BlockingQueue<String> queue; 
    private volatile boolean keepRunning = true; 

    public Consumer(BlockingQueue<String> queue) { 
    this.queue = queue; 
    } 

    @Override 
    public void run() { 
    while (keepRunning) { 
     String value; 
     try { 
     value = queue.take(); 
     } catch(InterruptedException e) { 
     throw new RuntimeException(e); 
     } 
     System.out.println(value); 
    } 
    } 
} 

EDITThe execution is stuck at queue.take() in Consumer Class. 私のメインクラスです誰も私がこの問題を解決する助けてくださいことはできますか?消費者に執行が滞っているのはなぜですか?

+1

なぜあなたはそれが_stuck_すべきではないと思いますか?あなたのコードのどの部分があなたの 'Consumer'' Runnable'を完了させ、対応する' Future'を完成させますか? –

+0

説明していただけますか?また、私がプロデューサに入れたオブジェクトを100に増やすと、100アイテムすべてが印刷されません。アイテムの乱数が印刷され、スタックされます。私はkeepRunningをfalseに変更していないことを知っていますが、私はそれを偽にする必要がある状態を知りません。 – Newbie

答えて

0

一つの可能​​な解決策:

1)生産側では、オリジナルの10のプットの後に "END" 信号置く:消費者側では

queue.put("END"); 

2)を、一度 "END" 信号を検出し、ブレークループ:

public void run() { 
while (keepRunning) { 
    String value; 
    try { 
    value = queue.take(); 
    if(value.equals("END")) { 
     System.out.println("Get END signal. All done!"); 
     break; 
    } 
    } catch(InterruptedException e) { 
    throw new RuntimeException(e); 
    } 
    System.out.println(value); 
} 

}

関連する問題