-1

スレッドのマルチスレッドおよびプロセス間通信を学習しようとしています。典型的なproducer-consumer問題を実装しました。しかし、出力は理想的にスレッドで作業している間にはならないかなり連続的です。Javaスレッド|プロデューサー消費者:コードに何が問題なのですか?

ので、ここで完全なコードで、[OK]を:今、私はプログラムを実行すると、プロデューサーのスレッドがある

public class Consumer implements Runnable { 

/* (non-Javadoc) 
* @see java.lang.Runnable#run() 
*/ 
@Override 
public void run() { 

    for(int i=1;i<=10;i++){ 
     ProducerConsumerSimulation.simulation.consume(); 
    } 

} 

} 

public class ProducerConsumerSimulation { 


public static ProducerConsumerSimulation simulation = new ProducerConsumerSimulation(); 


private Queue<Integer> sharedQueue = new LinkedList<Integer>(); 

private int MAX_LIMIT = 10; 

public void produce(int i){ 
    synchronized (sharedQueue) { 
     while(true){ 


      while(sharedQueue.size()==MAX_LIMIT){ 
       try { 
        sharedQueue.wait(); 
       } catch (InterruptedException e) { 
        e.printStackTrace(); 
       } 
      } 
      sharedQueue.add(i); 
      System.out.println("Produced: "+i); 
      sharedQueue.notifyAll(); 
      return; 


     } 
    } 
} 

public void consume() { 
    synchronized (sharedQueue) { 
     while (true) { 


      while (sharedQueue.isEmpty()) { 
       try { 
        sharedQueue.wait(); 
       } catch (InterruptedException e) { 
        e.printStackTrace(); 
       } 
      } 
      int i = sharedQueue.remove(); 
      System.out.println("Consumed: " + i); 
      sharedQueue.notifyAll(); 
      return; 


     } 
    } 
} 

/** 
* @param args 
*/ 
public static void main(String[] args) { 


    for(int i=1;i<=5;i++){ 

     Runnable p = new Producer(); 
     Thread prod = new Thread(p); 
     prod.start(); 
    } 
    for(int i=1;i<=5;i++){ 

     Runnable c = new Consumer(); 
     Thread con = new Thread(c); 
     con.start(); 
    } 


} 

} 

生産者スレッド:

public class Producer implements Runnable { 

/* (non-Javadoc) 
* @see java.lang.Runnable#run() 
*/ 
@Override 
public void run() { 

    for(int i=1;i<=10;i++){ 
     ProducerConsumerSimulation.simulation.produce(i); 
    } 

} 

} 

消費者スレッド消費者より常に最初に走っています。複数のプロデューサ/コンシューマを作成しても結果は同じです。以下は、1つのプロデューサとシングル・コンシューマに出力されます:

Produced: 1 
Produced: 2 
Produced: 3 
Produced: 4 
Produced: 5 
Produced: 6 
Produced: 7 
Produced: 8 
Produced: 9 
Produced: 10 
Consumed: 1 
Consumed: 2 
Consumed: 3 
Consumed: 4 
Consumed: 5 
Consumed: 6 
Consumed: 7 
Consumed: 8 
Consumed: 9 
Consumed: 10 

誰かがここでの挙動を説明できますか?私はここで多くの答えを行ったが、間違って実装されているかどうかを理解したい。

+0

ループ全体が同期ブロックにあります。 1つのスレッドは、他のスレッドが完全に終了するまでスタックされます。 – shmosel

+1

@shmosel私もそうだと思っていましたが、実際には、ループ内にリターンがあり、このループは完全に役に立たなくなりました(しかし非常に混乱します)。 –

+0

@JBNizet良い点。おそらくwait/notifyループパターンの誤解。 – shmosel

答えて

2

まず最初に反復した後に戻ってから実際に1回だけ実行する2つのループwhile (true)を削除する必要があります。それはあなたのコードをかなり混乱させます。

質問:プロデューサとコンシューマの両方が、2つの制作/消費の間に何もしません。彼らは直ちに同期ブロックに再び入り、キューとの間で何かを出し入れします。より現実的な例では、値をキューに入れる前に値を生成するのに時間がかかり、キューから取得した値で何らかの処理を行うのに時間がかかります。 produce()またはconsume()の各呼び出しの後に任意の遅延を導入すると、より多くのインターレースの制作物と消費を見ることになります。

最後に、LinkedList、同期ブロック、およびwait/notifyAllの呼び出しを使用して、ホイールを再開発していることに注意してください。 BlockingQueueを使うだけでよいでしょう。

+0

良い点。私はブロッキング・キューも理解していますが、待っている/通知することでバックグラウンドを理解したかったのです。睡眠を追加してランダム化をチェックしようとします。 –

関連する問題