2012-04-23 50 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中使用它。