2015-10-14 213 views
0

我試圖與一個生產者和一個消費者實現生產者 - 消費者問題。生產者不能製造超過五種產品。如果沒有,消費者不能消費產品。Java生產者 - 消費者:生產者不「通知()」消費者

我在需要時將它們鎖定在名爲「monitor」的字段上。

這裏是我的代碼:

import java.util.concurrent.TimeUnit; 

public class ConsumerProducer { 

private static final Object monitor = new Object(); 
private final int MAX_PRODUCTS = 5; 
private String[] products = new String[MAX_PRODUCTS]; 

int slotToProduce = 0; 
int slotToConsume = 0; 

private Thread producer = new Thread(new Producer()); 
private Thread consumer = new Thread(new Consumer()); 

class Producer implements Runnable { 

    private synchronized void produce() { 
     synchronized (monitor) { 
      // Acquiring access to produce a product 
      while (slotToProduce - slotToConsume == MAX_PRODUCTS) { 
       try { 
        this.wait(); 
       } catch (InterruptedException e) { 
       } 
      } 

      // Producing a product 
      System.out.println("Will now produce product " + slotToProduce); 
      try { 
       TimeUnit.SECONDS.sleep(1); 
      } catch (InterruptedException e) { 
      } 
      products[slotToProduce % MAX_PRODUCTS] = "Teddy Bear " 
        + Integer.toString(slotToProduce); 
      System.out.println("Successfully produced product " 
        + products[slotToProduce % MAX_PRODUCTS]); 
      slotToProduce++; 

      // Notifying consumers if there were no products before 
      if (slotToProduce - slotToConsume == 1) { 
       notify(); 
      } 
     } 
    } 

    @Override 
    public void run() { 
     while (true) { 
      produce(); 
     } 
    } 

} 

class Consumer implements Runnable { 

    private synchronized void consume() { 
     synchronized (monitor) { 
      // Acquiring access to consume a product 
      while (slotToProduce == slotToConsume) { 
       try { 
        this.wait(); 
       } catch (InterruptedException e) { 
       } 
      } 

      // Consuming a product 
      System.out.println("Will now consume product " 
        + products[slotToConsume % MAX_PRODUCTS]); 
      try { 
       TimeUnit.SECONDS.sleep(1); 
      } catch (InterruptedException e) { 
      } 
      System.out.println("Successfully consumed product " 
        + products[slotToConsume % MAX_PRODUCTS]); 
      slotToConsume++; 

      // Notifying producers if before there were no spaces to produce 
      // a product 
      if (slotToProduce - slotToConsume == MAX_PRODUCTS - 1) { 
       notify(); 
      } 
     } 
    } 

    @Override 
    public void run() { 
     while (true) { 
      consume(); 
     } 
    } 
} 

public static void main(String args[]) { 
    final ConsumerProducer cp = new ConsumerProducer(); 
    cp.producer.start(); 
    cp.consumer.start(); 
} 

}

然而,當我運行我的程序,輸出結果是:

  • 現在生產的產品0
  • 成功生產產品泰迪熊0
  • 現將生產產品1
  • 成功地生產產品泰迪熊1
  • 現在將產生的產物2
  • 成功地生產產品泰迪熊2
  • 現在會產生產品3
  • 成功地生產產品泰迪熊3
  • 現在將產生的產品4
  • 成功地生產產品泰迪熊4

和FR在這裏關於程序暫停。

所以問題是:即使我同時使消費者和生產者在同一個對象「顯示器」上同步,爲什麼消費者一直在睡覺?

回答

3

您正在同步顯示器對象。但是你調用sleep並通知生產者和消費者對象。

所需的更改:

  1. 調用等待(),通知()監視器上
  2. 刪除synchonized上的方法。只保留監視器對象上的同步。
  3. 永遠不會忽略中斷的異常!
  4. 想一想使用隊列。看看接口java.util.concurrent.BlockingQueue
+0

謝謝,這解決了停止問題! – mercury0114