Java 學習筆記 使用synchronized實現生產者消費者模式


說明

  • Object.wait()使當前的線程進入到等待狀態(進入到等待隊列)
  • Object.notifyAll() 喚醒等待中的全部線程
  • Object.notify() 隨機喚醒一個線程

代碼

consumer.java

public class Consumer extends Thread {
    List<Object> container;
    /*表示當前線程共生產了多少件物品*/
    private int count;

    public Consumer(String name, List<Object> container) {
        super(name);
        this.container = container;
    }

    @Override
    public void run() {

        while(true){
            synchronized (container) {
                try {
                    if (container.isEmpty()) { //倉庫已空,不能消 只能等
                        container.wait(20);

                    } else {
                        // 消費
                        container.remove(0);
                        this.count++;
                        System.out.println("消費者:" + getName() + " 共消費了:" + this.count + "件物品,當前倉庫里還有" + container.size() + "件物品");
                        container.notifyAll();  // 喚醒等待隊列中所有線程
                    }

                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }

            try {
                sleep(10);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }
}

Producer.java

public class Producer extends Thread{

    List<Object> container;
    /*表示當前線程共生產了多少件物品*/
    private int count;

    public Producer(String name, List<Object> container) {
        super(name);
        this.container = container;
    }

    @Override
    public void run() {
        while (true) {
            synchronized (container) {
                try {
                    // 如果某一個生產者能執行進來,說明此線程具有container對象的控制權,其它線程(生產者&消費者)都必須等待
                    if (container.size() == 10) { // 假設container最多只能放10個物品,即倉庫已滿
                        container.wait(10); //表示當前線程需要在container上進行等待
                    } else {
                        // 倉庫沒滿,可以放物品
                        container.add(new Object());
                        this.count++;
                        System.out.println("生產者:" + getName() + " 共生產了:" + this.count + "件物品,當前倉庫里還有" + container.size() + "件物品");
                        // 生產者生產了物品后應通知(喚醒)所有在container上進行等待的線程(生產者&消費者)
                        //   生:5, 消:5
                        // container.notify();  // 隨機喚醒一個在等待隊列中的線程
                        container.notifyAll();  // 喚醒等待隊列中所有線程
                    }
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            } //

            try {
                sleep(20);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }
}

Test.java

public class Test {

    public static void main(String[] args) {
        // 倉庫
        List<Object> container = new ArrayList<>();

        new Producer("老王", container).start();
        new Consumer("小芳", container).start();
        new Producer("老李", container).start();
        new Consumer("小荷", container).start();
        new Producer("老張", container).start();

        new Consumer("小花", container).start();
        new Producer("老劉", container).start();
        new Consumer("小妞", container).start();
        new Consumer("小米", container).start();
        new Producer("老馬", container).start();

    }
}


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM