0

プロデューサー/コンシューマー pgm を実装しようとしています。共有リソースはキュー (オブジェクトの配列 - サイズ 5) です。プロデューサはオブジェクトを追加し、コンシューマに通知します。q がいっぱいになると待機します。コンシューマは、q が空になると待機します。

理解できないのは

  1. Producer が obj を追加した後に通知すると、consumer は待機状態にならないため、プロデューサーは 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 に答える