天天看點

經典案例:生産者-消費者模型 | 帶你學《Java語言進階特性》之十一

上一篇:同步的缺陷-死鎖問題 | 帶你學《Java語言進階特性》之十

【本節目标】

通過閱讀本節内容,你将初步了解生産者-消費者操作的内容,并能使用線程相關方法簡單實作這個操作,初步了解到這一操作中的線程不同步問題與重複操作問題。

在多線程的開發過程之中最為著名的案例就是生産者和消費者操作,該操作的主要流程如下:

生産者負責資訊内容的生産;

每當生産者生産完成一項完整的資訊之後消費者要從這裡面取走資訊;

如果生産者沒有生産完則消費者要等待它生産完成,如果消費者還沒有對資訊進行消費,則生産者應該等待消費處理完成後再繼續生産。

程式的基本實作

可以将生産者和消費者定義為兩個獨立的線程類對象,但是對于現在生産的資料,可以使用如下的組成:

資料1:title=王建、content=宇宙大帥哥;

資料2:title=小高、content=猥瑣第一人;

既然生産者與消費者是兩個獨立的線程,那麼這兩個獨立的線程就需要有一個資料的儲存集中點,那麼可以單獨定義一個Message類來實作資料的儲存。

經典案例:生産者-消費者模型 | 帶你學《Java語言進階特性》之十一

圖一 生産者與消費者

範例:程式基本結構

class Producer implements Runnable {
    private Message msg;
    public Producer(Message msg) {
        this.msg = msg;
    }
    @Override
    public void run() {
        for (int x = 0; x < 100; x++) {
            if (x % 2 == 0) {
                this.msg.setTitle("王健");
                try {
                    Thread.sleep(100);     //模拟網絡延遲
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                this.msg.setContent("宇宙大帥哥");
            } else {
                this.msg.setTitle("小高");
                try {
                    Thread.sleep(100);    //模拟網絡延遲
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                this.msg.setContent("猥瑣第一人,常态保持。");
            }
        }
    }
}
class Consumer implements Runnable {
    private Message msg;
    public Consumer(Message msg) {
        this.msg = msg;
    }
    @Override
    public void run() {
        for (int x = 0; x < 100; x++) {
            try {
                Thread.sleep(10);   //模拟網絡延遲
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            System.out.println(this.msg.getTitle() + " - " + this.msg.getContent());
        }
    }
}
class Message {
    private String title;
    private String content;
    public void setContent(String content) {
        this.content = content;
    }
    public void setTitle(String title) {
        this.title = title;
    }
    public String getContent() {
        return content;
    }
    public String getTitle() {
        return title;
    }
}

public class ThreadDemo {
    public static void main(String[] args) throws Exception {
        Message msg = new Message();
        new Thread(new Producer(msg)).start();    //啟動生産者線程
        new Thread(new Consumer(msg)).start();   //啟動消費者線程
    }
}           
經典案例:生産者-消費者模型 | 帶你學《Java語言進階特性》之十一

圖二 執行結果圖

通過整個代碼的執行,會發現此時有兩個主要問題:

  • 問題一:資料不同步了;
  • 問題二:生産一個取走一個,但是發現有了重複生産和重複取出的問題;

想學習更多的Java的課程嗎?從小白到大神,從入門到精通,更多精彩不容錯過!免費為您提供更多的學習資源。

本内容視訊來源于

阿裡雲大學 下一篇:一文速解生産者-消費者模式問題 | 帶你學《Java語言進階特性》之十二 更多Java面向對象程式設計文章檢視此處