0

我正在尝试实现生产者-消费者 pgm。共享资源是队列(对象数组,大小为 5)。生产者添加一个对象并通知消费者,当 q 已满时等待。消费者在 q 为空时等待,否则读取/删除并通知生产者它已完成。

无法理解的是

  1. 当 Producer 添加 obj 后通知时,消费者不会处于等待状态,所以 Producer 继续生产,直到 q 已满。

任何人都可以帮助如何克服这个问题。我知道某个简单的地方失踪但无法弄清楚:(

class Queue
{
  public void add(Object item) 
  {
   q[index] = item;
   index++;
  }
  public Object get()
  { 
   Object item = q[index - 1];
   index--;
   return item;
  }
  public boolean isQfull()
  {
System.out.println("Queue:index-->" + index);
if(index == 5)
{
 return true;
}
return false;
  }

  public boolean isQEmpty()
  {
   if(index == 0)
{
 System.out.println("Queue:isQEmpty");
 return true;           
}
 return false;
  }
}

class Producer extends Thread 
{
 public void run()
 {
  synchronized(q)
  {
   for(int i=0;i<20;i++)
   {
    if(q.isQfull())
    {
     q.wait();
    }
    else
    {
     q.add(i);                      
     q.notify();                        
    }
   }
 }
}
public class Consumer extends Thread
{
 public void run()
 {
  synchronized(q)
  {
   while(true)
{
 if(q.isQEmpty())
 {
  q.wait();                     
 }
 else
 {
 System.out.println("Consumer consuming" + q.get());
 q.notify();
}
   }
  }
}

}

4

2 回答 2

1

http://docs.oracle.com/javase/7/docs/api/java/util/concurrent/BlockingQueue.html

您是否考虑过使用 java 并发包中的队列?您不必手动同步生产者和消费者。

编辑:

在这种情况下,您可能会忘记同步生产者和消费者。相反,让您的 Queue 类同步其 add 和 get 调用。

class Queue
private final Object lock = new Object();
{
  public void add(Object item) 
  {
    synchronized(lock) {
      q[index] = item;
      index++;
    }
  }
  public Object get()
  { 
    synchronized(lock) {
      Object item = q[index - 1];
      index--;
      return item;
    }
  }
}
于 2013-09-12T17:56:08.733 回答
1

这个问题需要重新措辞,但我相信问题是(与看起来像家庭作业的内容有关)......

“无法理解的是 1)当生产者在添加 obj 后通知时,消费者不会处于等待状态,所以生产者会继续生产直到 q 已满。有人可以帮忙解决这个问题吗?

Producer 类的逻辑似乎很清晰,实现也相当正确。也就是说,生产者只在队列保持满时才关心消费者活动。假设线程定期运行()以重新填充消费者正在从中删除条目的队列,生产者不应该等待(),而如果队列已满则简单地退出。

因此:

if (!q.isFull())
 ... add to queue and notify Consumers.

这里缺少的是消费者端需要等待()或在队列为空时定期检查(等待生产者补充队列)。

于 2013-09-12T18:00:39.583 回答