Java多線程:“基礎篇”11之生產消費者問題

來源:互聯網
上載者:User

1. 生產/消費者模型

生產/消費者問題是個非常典型的多線程問題,涉及到的對象包括“生產者”、“消 費者”、“倉庫”和“產品”。他們之間的關係如下:

(01) 生產者僅僅在倉儲未滿時候生產,倉滿則停止生產。

(02) 消費者僅僅在倉儲有產品時候才能消費,倉空則等待。

(03) 當消費者發現倉儲沒產品可消費時候會通知生產者生產。

(04) 生產者在生產出可消費產品時候,應該通知等待的消費者去消費。

2. 生產/消費者實現

下面通過wait()/notify()方式實現該模型(後面在學習了線程池相關內容之後,再通過其它方式實現 生產/消費者模型)。源碼如下:

// Demo1.java// 倉庫class Depot {    private int capacity;    // 倉庫的容量    private int size;        // 倉庫的實際數量        public Depot(int capacity) {        this.capacity = capacity;        this.size = 0;    }        public synchronized void produce(int val) {        try {             // left 表示“想要生產的數量”(有可能生產量太多,需多此生產)            int left = val;            while (left > 0) {                // 庫存已滿時,等待“消費者”消費產品。                while (size >= capacity)                    wait();                // 擷取“實際生產的數量”(即庫存中新增的數量)                // 如果“庫存”+“想要生產的數量”>“總的容量”,則“實際增量”=“總的容量”-“當前容量”。(此時填滿倉庫)                // 否則“實際增量”=“想要生產的數量”                int inc = (size+left)>capacity ? (capacity-size) : left;                size += inc;                left -= inc;                System.out.printf("%s produce(%3d) --> left=%3d, inc=%3d, size=%3d\n",                         Thread.currentThread().getName(), val, left, inc, size);                // 通知“消費者”可以消費了。                notifyAll();            }        } catch (InterruptedException e) {        }    }         public synchronized void consume(int val) {        try {            // left 表示“客戶要消費數量”(有可能消費量太大,庫存不夠,需多此消費)            int left = val;            while (left > 0) {                // 庫存為0時,等待“生產者”生產產品。                while (size <= 0)                    wait();                // 擷取“實際消費的數量”(即庫存中實際減少的數量)                // 如果“庫存”<“客戶要消費的數量”,則“實際消費量”=“庫存”;                // 否則,“實際消費量”=“客戶要消費的數量”。                int dec = (size<left) ? size : left;                size -= dec;                left -= dec;                System.out.printf("%s consume(%3d) <-- left=%3d, dec=%3d, size=%3d\n",                         Thread.currentThread().getName(), val, left, dec, size);                notifyAll();            }        } catch (InterruptedException e) {        }    }        public String toString() {        return "capacity:"+capacity+", actual size:"+size;    }}     // 生產者class Producer {    private Depot depot;            public Producer(Depot depot) {        this.depot = depot;    }        // 消費產品:建立一個線程向倉庫中生產產品。    public void produce(final int val) {        new Thread() {            public void run() {                depot.produce(val);            }        }.start();    }}    // 消費者class Customer {    private Depot depot;            public Customer(Depot depot) {        this.depot = depot;    }        // 消費產品:建立一個線程從倉庫中消費產品。    public void consume(final int val) {        new Thread() {            public void run() {                depot.consume(val);            }        }.start();    }}    public class Demo1 {      public static void main(String[] args) {          Depot mDepot = new Depot(100);        Producer mPro = new Producer(mDepot);        Customer mCus = new Customer(mDepot);            mPro.produce(60);        mPro.produce(120);        mCus.consume(90);        mCus.consume(150);        mPro.produce(110);    }}

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.