多線程 | 三種形式的生產者-消費者問題 java實現

1.synchronized+wait(),notify()/notifyAll()



import java.util.LinkedList;

public class ProducerAndConsumer2 {
    public static void main(String[] args) {
        Storage2 storage2 = new Storage2();
        //開啓生產者線程
        for (int i = 0;i < 6; i++){
            int finalI = i;
            new Thread(()-> storage2.produce2(String.format("生產者%d",finalI))).start();
        }

        //開啓消費者線程
        for (int i = 0; i < 5; i++){
            int finalI = i;
            new Thread(()->storage2.consume2(String.format("消費者%d",finalI))).start();
        }

    }
}

class Storage2{
    //倉庫的最大容量
    private final int MAX_SIZE = 100;
    //倉庫存儲的載體
    private LinkedList<Object> list = new LinkedList<>();

    //生產產品
    public void produce2(String producer){
        synchronized (list){
            while (list.size() == MAX_SIZE){
                System.out.println("倉庫已滿,【"+producer+"】:暫時不能執行生產任務!");
                try {
                    //由於條件不滿足,生產阻塞
                    list.wait();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
            list.add(new Object());
            System.out.println("生產者"+producer+"生產了一個產品");
            list.notifyAll();
        }
    }

    //消費產品
    public void consume2(String consumer){
        synchronized (list){
            while (list.size() == 0){
                System.out.println("倉庫已空,【"+consumer+"】:暫時不能執行消費任務!");
                try {
                    list.wait();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
            list.remove();
            System.out.println("消費者"+consumer+"消費了一個產品!");
            list.notifyAll();
        }
    }
}

 

2.顯示鎖Lock+Condition

package ConcurrentProgramme;

import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;

public class ProducerAndConsumer3Condition {
    public static void main(String[] args) {
        Storage3 storage3 = new Storage3();

        for (int i = 0; i < 6; i++){
            int finalI = i;
            new Thread(()->storage3.push("生產者"+finalI)).start();
        }

        for (int j = 0; j < 6; j++){
            int finalI = j;
            new Thread(()->storage3.poll("消費者"+finalI)).start();
        }
    }
}
class Storage3{
    int count = 0; //容量爲5
    final static Lock key = new ReentrantLock();  //顯示鎖
    final static Condition full = key.newCondition();   //兩種不同狀態的Condition實例
    final static Condition empty = key.newCondition();
    public void push(String producer){
        key.lock();
        try{
            while (count == 5){
                System.out.println("容器已滿,"+producer+"生產者阻礙!");
                try {
                    full.await();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
            count++;   //增加一個產品
            System.out.println("生產者"+producer+"生產一個產品!現在容器中有"+count +"個產品");
            empty.signalAll(); //喚醒其他消費者線程
        }finally {
            key.unlock();
        }

    }

    public void poll(String consumer){
        key.lock();
        try{
            while (count == 0){
                System.out.println("容器爲空,消費者"+consumer+"阻礙!");
                try {
                    empty.await();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
            count--;
            System.out.println("消費者"+consumer+"消費一個產品!現在容器中有"+count +"個產品");
            full.signalAll();
        }finally {
            key.unlock();
        }

    }
}

 

3.BlockingQueue

package ConcurrentProgramme;

import java.util.concurrent.LinkedBlockingQueue;


public class ProducerAndConsumer4BlockQueue {
    public static void main(String[] args) {
        Storage4 storage4 = new Storage4();

        for (int i = 0; i < 6; i++){
            int finalI = i;
            new Thread(()->storage4.push("生產者"+finalI)).start();
        }

        for (int j = 0; j < 6; j++){
            int finalI = j;
            new Thread(()->storage4.poll("消費者"+finalI)).start();
        }

        /*Producer4 p = new Producer4(storage4);
        Consumer4 s = new Consumer4(storage4);
        p.start();
        s.start();*/
    }
}

class Producer4 extends Thread{
    private Storage4 storage4;
    public Producer4(Storage4 storage4){
        this.storage4 = storage4;
    }
    public void run(){
        for (int i = 0; i < 6;i++){
            storage4.push("生產者");
            /*try {
                Thread.sleep(100);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }*/
        }
    }
}

/*class Consumer4 extends Thread{
    private Storage4 storage4;
    public Consumer4(Storage4 storage4){
        this.storage4 = storage4;
    }
    public void run(){
        for (int i = 0; i < 6;i++){
            storage4.poll("消費者");
        }
    }
}*/
class Storage4{
    private final int MAX_SIZE = 100;
    private LinkedBlockingQueue<Object> list = new LinkedBlockingQueue<>(100);
    public void push(String producer){
        if (list.size() == MAX_SIZE ){
            System.out.println("容器已滿,"+producer+"生產者阻礙!");
        }

        try {
            list.put(new Object());
            //在讀大小的時候有髒數據????
            System.out.println("生產者"+producer+"生產一個產品!現在容器中有"+(list.size()-1)+"個產品");
        } catch (InterruptedException e) {
            e.printStackTrace();
        }



    }

    public void poll(String consumer){
        if (list.size() == 0){
            System.out.println("容器爲空,消費者"+consumer+"阻礙!");
        }

        try {
            list.take();
            System.out.println("消費者"+consumer+"消費一個產品!現在容器中有"+(list.size()-1) +"個產品");
        } catch (InterruptedException e) {
            e.printStackTrace();
        }


    }
}

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章