2016-08-07 95 views
1

我想寫一個生產者消費者程序在Java中生產者在隊列中插入3個數字和消費者從隊列中刪除這些數字。我已經根據自己的Linkedlist實現實現了自己的隊列。Java線程生產者消費者程序

當我運行我的代碼時,我的生產者終止,但我的消費者永遠不會終止。我無法弄清楚爲什麼

public class ProdConMain { 

public static void main(String[] args) throws InterruptedException { 

    MyQueue queue = new MyQueue(); 
    queue.setLimit(3); 
    Thread producer = new Thread(new Producer(queue)); 
    Thread consumer = new Thread(new Consumer(queue)); 

    producer.start(); 
    consumer.start(); 


    try { 
     producer.join(); 
     System.out.println("Producer: " + producer.getState()); 
     consumer.join(); 

     System.out.println("Consumer: " + consumer.getState()); 
    } catch (InterruptedException e) { 
     e.printStackTrace(); 
    } 

    System.out.println(queue.list.toString()); 

} 


} 



public class Producer implements Runnable { 

MyQueue queue = new MyQueue(); 
Random random = new Random(); 
public Producer(MyQueue queue) { 
    this.queue = queue; 
} 

@Override 
public void run() { 
    int i = 1; 
    while (i < 10) { 

     synchronized (queue) { 
      if (queue.getSize() < queue.getLimit()) { 
       int value = random.nextInt(500); 
       queue.enqueue(value); 
       System.out.println("Inserted: " + value); 
       queue.notify(); 
      } else { 
       try { 
        queue.wait(); 
       } catch (InterruptedException e) { 
        e.printStackTrace(); 
       } 
      } 
     } 

     i++; 
    } 
    } 
} 


public class Consumer implements Runnable { 

    MyQueue queue = new MyQueue(); 

    public Consumer(MyQueue queue) { 
    this.queue = queue; 
} 

    @Override 
    public void run() { 

    while (true) { 
     synchronized (queue) { 

      if (queue.isEmpty()) { 
       { 
        try { 
         queue.wait(); 
        } catch (InterruptedException e) { 
         e.printStackTrace(); 
        } 
       } 
      } else { 
       int value = queue.dequeue(); 
       System.out.println("Removed:  " + value); 
       queue.notify(); 
      } 
     } 
    } 
    } 
} 
+0

'消費者'永遠不會終止,因爲你正在使用無限循環'while(true)' –

回答

0

你需要一個停止條件添加到而(真)在消費者循環,否則將永遠不會結束。您可以在條件本身做到這一點:

while(shouldConsume()) { 
    // consume ... 
} 

或打破無限循環如果達到條件:

while(true) { 
    // consume ... 

    if (shouldStopConsume()) { 
     break; 
    } 
} 

然後你只需要實現與停止那些方法適合您的用例的條件。

+0

我明白了,謝謝。現在它適用於我。 隊列類 - public volatile boolean doneProcessing; (實例變量) 生產者類 - queue.doneProcessing = true; (從while循環退出後) 使用者類 - while(!queue.doneProcessing) – Jehan