1. 程式人生 > >使用管程實現生產者消費者模式

使用管程實現生產者消費者模式

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 class
Monitor { /** * 互斥量,集合內的成品數量 */ 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();
    }
}

需要註意的是,在測試方法裏,每個線程要使用同一個實例。

使用管程實現生產者消費者模式