java實現生產者消費者問題

引言 java

  生產者和消費者問題是線程模型中的經典問題:生產者和消費者在同一時間內共用同一個存儲空間,以下圖所示,生產者向空間裏存放數據,而消費者取用數據,若是不加以協調可能會出現如下狀況: dom

生產者消費者圖 spa

  存儲空間已滿,而生產者佔用着它,消費者等着生產者讓出空間從而去除產品,生產者等着消費者消費產品,從而向空間中添加產品。互相等待,從而發生死鎖。 線程

JAVA解決線程模型的三種方式 code

  一、wait()和notify() 對象

複製代碼
import java.util.LinkedList; public class ProducerConsumer { private LinkedList<Object> storeHouse = new LinkedList<Object>(); private int MAX = 10; public ProducerConsumer() { } public void start() { new Producer().start(); new Comsumer().start(); } class Producer extends Thread { public void run() { while (true) { synchronized (storeHouse) { try { while (storeHouse.size() == MAX) { System.out.println("storeHouse is full , please wait"); storeHouse.await(); } Object newOb = new Object(); if (storeHouse.add(newOb)) { System.out.println("Producer put a Object to storeHouse"); Thread.sleep((long) (Math.random() * 3000)); storeHouse.signal(); } } catch (InterruptedException ie) { System.out.println("producer is interrupted!"); } } } } } class Comsumer extends Thread { public void run() { while (true) { synchronized (storeHouse) { try { while (storeHouse.size() == 0) { System.out.println("storeHouse is empty , please wait"); storeHouse.await(); } storeHouse.removeLast(); System.out.println("Comsumer get  a Object from storeHouse"); Thread.sleep((long) (Math.random() * 3000)); storeHouse.signal(); } catch (InterruptedException ie) { System.out.println("Consumer is interrupted"); } } } } } public static void main(String[] args) throws Exception { ProducerConsumer pc = new ProducerConsumer(); pc.start(); } }
複製代碼

 

  二、await()和signal(),即線程鎖的方式 隊列

複製代碼
package sort; import java.util.LinkedList; import java.util.concurrent.locks.Condition; import java.util.concurrent.locks.Lock; import java.util.concurrent.locks.ReentrantLock; public class ProducerConsumer { private LinkedList<Object> myList = new LinkedList<Object>(); private int MAX = 10; private final Lock lock = new ReentrantLock(); private final Condition full = lock.newCondition(); private final Condition empty = lock.newCondition(); public ProducerConsumer() { } public void start() { new Producer().start(); new Consumer().start(); } public static void main(String[] args) throws Exception { ProducerConsumer s2 = new ProducerConsumer(); s2.start(); } class Producer extends Thread { public void run() { while (true) { lock.lock(); try { while (myList.size() == MAX) { System.out.println("warning: it's full!"); full.await(); } Object o = new Object(); if (myList.add(o)) { System.out.println("Producer: " + o); empty.signal(); } } catch (InterruptedException ie) { System.out.println("producer is interrupted!"); } finally { lock.unlock(); } } } } class Consumer extends Thread { public void run() { while (true) { lock.lock(); try { while (myList.size() == 0) { System.out.println("warning: it's empty!"); empty.await(); } Object o = myList.removeLast(); System.out.println("Consumer: " + o); full.signal(); } catch (InterruptedException ie) { System.out.println("consumer is interrupted!"); } finally { lock.unlock(); } } } } }
複製代碼

 

  三、阻塞隊列的方式 rem

複製代碼
import java.util.concurrent.*; public class ProducerConsumer { // 創建一個阻塞隊列 private LinkedBlockingQueue<Object> queue = new LinkedBlockingQueue<Object>(10); public ProducerConsumer() { } public void start() { new Producer().start(); new Consumer().start(); } public static void main(String[] args) throws Exception { ProducerConsumer s3 = new ProducerConsumer(); s3.start(); } class Producer extends Thread { public void run() { while (true) { try { Object o = new Object(); // 取出一個對象  queue.put(o); System.out.println("Producer: " + o); } catch (InterruptedException e) { System.out.println("producer is interrupted!"); } // }  } } } class Consumer extends Thread { public void run() { while (true) { try { // 取出一個對象 Object o = queue.take(); System.out.println("Consumer: " + o); } catch (InterruptedException e) { System.out.println("producer is interrupted!"); } // }  } } } }
複製代碼

結論 get

  三種方式原理一致,都是對獨佔空間加鎖,阻塞和喚醒線程,第一種方式比較傳統,第三種方式最簡單,只需存儲和取用,線程同步的操做交由LinkedBlockingQueue全權處理。 同步

相關文章
相關標籤/搜索