2015-06-05 250 views
0

我試圖實施生產者消費者模式與wait()notifyAll()方法,但有一些問題。所以我的代碼是下一個。生產消費者

主類

import java.util.LinkedList; 
import java.util.List; 

public class TestThread { 

    public static void main(String[] args) { 
     final List testQueue = new LinkedList(); 

     final Producer producer = new Producer(testQueue); 
     final Consumer consumer = new Consumer(testQueue); 

     Runnable prodThread = new Runnable() { 
      @Override 
      public void run() { 
       producer.putMessages(); 
      } 
     }; 
     Runnable consThread = new Runnable() { 
      @Override 
      public void run() { 
       consumer.readMessages(); 
      } 
     }; 

     (new Thread(prodThread)).start(); 
     (new Thread(consThread)).start(); 
    } 
} 

農產品類

class Producer { 
    private final List queue; 

    public Producer(List queue) { 
     this.queue = queue; 
    } 

    public void putMessages() { 
     // Add batch of messages to queue 
     for (int t = 1; t <= 2; t++) { 
      synchronized (queue) { 
       try { 
        // if size of queue is more then 2, then wait 
        while (queue.size() > 1) { 
         System.out.println("Producer: Queue is full! Size of queue is " + queue.size() +", so Producer is waiting..."); 
         queue.wait(); 
         // Consumer could start own work here 
        } 
        for (int i = 0; i < 2; i ++) { 
         queue.add("String" + (i+1)*t); 
         System.out.println("Producer: Message -" + queue.get(i) + "- was added to queue..."); 
        } 
        System.out.println("Producer added batch of messages, let's notify our Consumer..."); 
        queue.notifyAll(); // consumer thread should be in wait set 
       } 
       catch(Exception ex) { 
        ex.printStackTrace(); 
       } 
      } 
     } 
    } 
} 

消費類

class Consumer { 
    private final List queue; 

    public Consumer(List queue) { 
     this.queue = queue; 
    } 

    public void readMessages() { 
     synchronized (queue) { 
      try { 
       //while queue is empty let's wait - producer will get processor time in this case 
       while (queue.isEmpty()) { 
        System.out.println("Consumer: Queue is empty! Nothing to read, so Consumer is waiting..."); 
        queue.wait(); 
       } 
       for (int k = 0; k < queue.size(); k++) { 
        System.out.println("Consumer: Read messages from queue -" + queue.get(k) + " -"); 
       } 
       //clean our queue 
       queue.removeAll(queue); 
       if (queue.isEmpty()) { 
        System.out.println("Consumer finished reading, notify Producer that queue is empty, please start adding new messages for me!"); 
        queue.notifyAll(); 
       } 
      } catch (Exception ex) { 
       ex.printStackTrace(); 
      } 
     } 
    } 
} 

將R程序執行的esult:

Consumer: Queue is empty! Nothing to read, so Consumer is waiting... 
Producer: Message -String1- was added to queue... 
Producer: Message -String2- was added to queue... 
Producer added batch of messages, let's notify our Consumer... 
Consumer: Read messages from queue -String1 - 
Consumer: Read messages from queue -String2 - 
Consumer finished reading, notify Producer that queue is empty, please start adding new messages for me! 
Producer: Message -String2- was added to queue... 
Producer: Message -String4- was added to queue... 
Producer added batch of messages, let's notify our Consumer... 

根據我的代碼,我期待的是消費者監製String2String4)讀最後消息,並打印出結果。但是這不會發生,我的代碼有什麼問題?

+1

因爲消費者沒有循環。生產者循環,但不是消費者。 –

回答

1

運行消費者的線程根據預期進入readMessages()。這裏沒有循環機制,所以在消耗前兩個消息之後,它會繼續執行並退出該方法。

您的製作人正在通知所有感興趣的線程,表明隊列中有消息但消費者未在收聽。消費者存在的線程已終止。