1. 程式人生 > >生產者消費者模式程式碼簡單實現

生產者消費者模式程式碼簡單實現


看見有些作者在書上用synchronized同步鎖去實現,利用wait()和notify()發訊號。

其實鎖方法是沒辦法併發的,這樣做會把並行變成序列計算了。

訊號量最好是建立一個新的類包含生產者和消費者的訊號,再使用關鍵字volatile保證有序性。

程式碼如下:

public class Main {
    public static void main(String[]args){
        LinkedList<Integer>queen = new LinkedList<Integer>();
        Sign sign = new Sign();
        sign.iniSign();
        new Thread(new Business(new Productor(),queen,500,100,sign)).start();
        new Thread(new Business(new Customer(),queen,5,1000,sign)).start();
    }
} 
/**
 * 訊號
 */
public class Sign {
    public  volatile int sign_p = 0;
    public  volatile int sing_c = 0;

    public void iniSign(){
        this.sign_p = 1;
        this.sing_c = 0;
    }
} 


public class Business implements Runnable {
    Person person;
    LinkedList<Integer> queen;
    int len;
    int time;
    Sign sign;
    public Business(Person person,LinkedList<Integer> queen, int len,int time,Sign sign) {
        this.person = person;
        this.queen = queen;
        this.len = len;
        this.time = time;
        this.sign = sign;
    }
    @Override
    public void run() {
        person.doThis(queen,len,time,sign);
    }
}


public  interface Person {

    void doThis(LinkedList<Integer>queen,int len,int time,Sign sign);
} 


/**
 * 消費者,如果佇列無資料,無法消費
 */
public class Customer implements Person {
    public synchronized void doThis(LinkedList queen, int len, int time, Sign sign) {
        System.out.println("消費者就緒");
        while (true) {
            while (sign.sing_c == 0) {

            }
            try {
                Thread.sleep(time);
            } catch (InterruptedException e) {
            }
            if (queen.size() > 0) {
                System.out.println("消費者消費資料: " + queen.removeFirst());
                sign.sign_p = 1;//釋放生產訊號
            } else {
                sign.sing_c = 0; //凍結消費訊號
            }
        }
    }
}
public synchronized void doThis(LinkedList<Integer> queen, int len, int time,Sign sign) {
        System.out.printf("生產者就緒");
        int i = 0;
        while (true) {
            while(sign.sign_p == 0){
//                System.out.println("生產者阻塞!!!");
            }
            try {
                Thread.sleep(time);
            } catch (InterruptedException e) {
            }
            if (queen.size() < len) {
                queen.addLast(i);
                System.out.println("生產者,生產資料: " + i++);
                sign.sing_c = 1;//釋放消費訊號
            } else {
                sign.sign_p = 0; //凍結生產訊號
            }
        }
    }
}