使用管程實現生產者消費者模式
阿新 • • 發佈:2017-09-18
dex .com 完成 ble override date 有用 mut 生產者消費者模式
生產者消費者模式是一種常見的設計模式,掌握一種完美,穩定的實現方式非常有用,下面我就使用misa管程實現生產者消費者模式。
這種實現的優點:
1.穩定,不會出現死鎖現象
2.運行速度相對較快
話不多說,直接上代碼:
管程類:
package com.brave.test; import java.util.ArrayList; import java.util.List; /** * * @描述:管程區 * * @author <p>[email protected]<p> brave * * @date 2017-9-18 */ public classMonitor { /** * 互斥量,集合內的成品數量 */ private static int mutex = 0; /** * 緩沖區邊界 */ private static int N = 20; /** * 緩沖區 */ private static List<String> stuffArr = new ArrayList<String>(N); /** * * @描述:往緩沖區內存放數據(生產) * * @author<p>[email protected]<p> brave * * @date 2017-9-18 * * @param stuff * @throws InterruptedException */ public synchronized void insert(String stuff) throws InterruptedException{ /** * 循環驗證,當線程被喚醒後,重新檢測條件是否成立 */ while(mutex == N){ System.out.println("緩沖區已滿,喚醒消費者"); notifyAll(); wait(); System.out.println("==生產者被喚醒=="); } stuffArr.add(stuff); //互斥量加一 mutex++; //緩沖區有數據後喚醒消費者 if(mutex == 1)notifyAll(); } /** * * @描述:移除緩沖區內數據(消費) * * @author <p>[email protected]<p> brave * * @date 2017-9-18 * * @return * @throws InterruptedException */ public synchronized String remove() throws InterruptedException{ String result = null; while(mutex == 0){ System.out.println("緩沖區已空,喚醒生產者"); notifyAll(); wait(); System.out.println("==消費者被喚醒=="); } result = stuffArr.remove(0); mutex--; if(mutex == N-1)notifyAll(); return result; } }
生產者:
package com.brave.test; public class Producers implements Runnable { private Monitor monitor = null; public Producers(Monitor monitor) { this.monitor = monitor; } @Override public void run() { int num = 1; while(true){ System.out.println("開始生產商品"); try { Thread.sleep(1000); System.out.println("商品生產完成:第【" + num + "】件商品"); monitor.insert("第【" + num++ + "】件商品"); } catch (InterruptedException e) { e.printStackTrace(); } } } }
消費者:
package com.brave.test; public class Consumers implements Runnable { private Monitor monitor = null; private String name = null; public Consumers(String name ,Monitor monitor) { this.monitor = monitor; this.name = name; } @Override public void run() { while(true){ System.out.println("開始消費商品"); try { System.out.println(name + "-->商品消費完成:" + monitor.remove() ); Thread.sleep(3000); } catch (InterruptedException e) { e.printStackTrace(); } } } }
測試類:
package com.brave.test; public class Test { public static void main(String[] args) { Monitor monitor = new Monitor(); Thread consumers1 = new Thread(new Consumers("一號消費者",monitor)); Thread consumers2 = new Thread(new Consumers("二號消費者",monitor)); Thread producers = new Thread(new Producers(monitor)); producers.start(); consumers1.start(); consumers2.start(); } }
需要註意的是,在測試方法裏,每個線程要使用同一個實例。
使用管程實現生產者消費者模式