2015-10-14 215 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