2012-04-23 123 views
2

这是生产者消费者模式的作业实现。下面的实现有什么问题。我已经搜索了各种实现,但我无法理解我的错误。在Java中实现生产者消费者

我有一个共享队列

我同步于相同的锁

实施

共享队列生产者和消费者:

class SharedQueue{ 
    public static Queue<Integer> queue = new LinkedList<Integer>(); 
} 

生产者线程:

//The producer thread 
class Producer implements Runnable{ 
    public void run() 
    { 
     synchronized (SharedQueue.queue) 
     { 
      if(SharedQueue.queue.size() >=5) 
      { 
       try { 
        SharedQueue.queue.wait(); 
       } catch (InterruptedException e) { 
        e.printStackTrace(); 
       } 
      } 
      Random r = new Random(); 

      int x = r.nextInt(10); 
      System.out.println("Inside Producer" + x); 

      SharedQueue.queue.offer(x); 


      SharedQueue.queue.notify(); 

     } 
    } 
} 

消费主题:

class Consumer implements Runnable{ 
    public void run() 
    { 
     synchronized (SharedQueue.queue) 
     { 
      if(SharedQueue.queue.size() == 0) 
      { 
       try { 
        SharedQueue.queue.wait(); 
       } catch (InterruptedException e) { 
        e.printStackTrace(); //To change body of catch statement use File | Settings | File Templates. 
       } 
      } 

      int k = SharedQueue.queue.remove(); 

      System.out.println("Inside consumer" + k); 
     } 
    } 
} 

主程序

public class ProducerConsumerTest { 

    public static void main(String[] args) 
    { 

     Thread p = new Thread(new Producer()); 
     Thread q = new Thread(new Consumer()); 

     p.start(); 
     q.start(); 

    } 
} 
+3

我不知道。哪里不对?什么地方出了错? [Stack Overflow不是心灵读者或水晶球。](http://meta.stackexchange.com/a/128551/133242) – 2012-04-23 02:46:51

+0

作为一般规则,更喜欢'java.util.concurrent'中的实用程序来使用代码等待和通知。(Effective Java,item 69) – 2012-04-23 02:53:11

回答

4

尝试更换:

if(SharedQueue.queue.size() >= 5) 

有:

while(SharedQueue.queue.size() >= 5) 

这:

if(SharedQueue.queue.size() == 0) 

有:

while(SharedQueue.queue.size() == 0) 

只是为了呼吁notify()后重新检查条件。

+0

如果我们用while(true){}包围同步块,是否仍然要求我们使用while(SharedQueue.queue.size()> = 5)而不是if(SharedQueue.queue。 size()> = 5)? – user2434 2012-04-23 04:10:16

+0

@ user2434是的,内部while循环用于在另一个线程调用'notify()'后再次检查条件。 – 2012-04-23 05:53:53

1

我假设你希望这是生产者消费者的无限循环。对Eng.Fouad 变化顶部,suround都synchonized块有:

 while (true) 

,并在消费者添加一个通知来实现生产者消费者问题

 int k = SharedQueue.queue.remove(); 

     // make the producer active again 
     SharedQueue.queue.notify(); 

     System.out.println("Inside consumer " + k); 
1

简单的方法是使用旗语。

public class Semaphore { 
    int value; 

    public Semaphore(int intialValue) { 
     this.value = intialValue; 
    } 

    public synchronized void p() { 
     while (value <= 0) { 
      try { 
       this.wait(); 
      } catch (InterruptedException e) { 
      } 
     } 
     value = value - 1; 
    } 

    public synchronized void v() { 
     value = value + 1; 
     this.notify(); 
    } 
} 

public class ProducerConsumerUsingSemaphore { 

    private static final int SIZE = 10; 

    public static void main(String[] args) { 

     Semaphore full = new Semaphore(0); 
     Semaphore empty = new Semaphore(SIZE); 
     Semaphore mutex = new Semaphore(1); 
     Vector<Integer> sQueue = new Vector<Integer>(); 

     Thread producerThread = new Thread(new Runnable() { 

      @Override 
      public void run() { 

       for (int i = 0; i < 5000; i++) { 
        empty.p(); 
        mutex.p(); 
        System.out.println(Thread.currentThread().getName() + " is trying to insert item " + i); 
        sQueue.add(i); 
        mutex.v(); 
        full.v(); 
       } 
      } 
     }); 

     Thread consumerThread = new Thread(new Runnable() { 

      @Override 
      public void run() { 
       while (true) { 
        full.p(); 
        mutex.p(); 
        System.out.println(Thread.currentThread().getName() + " consuming item " + sQueue.remove(0)); 
        mutex.v(); 
        empty.v(); 
       } 
      } 
     }); 

     producerThread.setName("Producer"); 
     consumerThread.setName("Consumer"); 

     consumerThread.start(); 
     producerThread.start(); 

    } 
} 
0

您可以使用ConcurrentLinkedQueue来管理生产者和消费者的共享队列。您可以使用ConcurrentHashMap> collection,这将有助于Producer同时生成,并且Consumer可以同时使用并将生成器生成的密钥保存在另一个集合对象中,其中Consumer可以找到它的密钥并从ConcurrentHashMap中使用它。