天天看點

生産者消費者模式淺析

由于最近工作中,涉及到生産者消費者設計模式,對此有一些體會,是以總結一下,與大家分享。

什麼是生産者消費者模式

在工作中,大家可能會碰到這樣一種情況:某個子產品負責産生資料,這些資料由另一個子產品來負責處理(此處的子產品是廣義的,可以是類、函數、線程、程序等)。産生資料的子產品,就形象地稱為生産者;而處理資料的子產品,就稱為消費者。在生産者與消費者之間在加個緩沖區,我們形象的稱之為倉庫,生産者負責往倉庫了進商品,而消費者負責從倉庫裡拿商品,這就構成了生産者消費者模式。

生産者消費者模式的優點

1、解耦

假設生産者和消費者分别是兩個類。如果讓生産者直接調用消費者的某個方法,那 麼生産者對于消費者就會産生依賴(也就是耦合)。将來如果消費者的代碼發生變化, 可能會影響到生産者。而如果兩者都依賴于某個緩沖區,兩者之間不直接依賴,耦合也 就相應降低了。

舉個例子,我們去郵局投遞信件,如果不使用郵筒(也就是緩沖區),你必須得把 信直接交給郵差。有同學會說,直接給郵差不是挺簡單的嘛?其實不簡單,你必須 得認識誰是郵差,才能把信給他(光憑身上穿的制服,萬一有人假冒,就慘了)。這 就産生和你和郵差之間的依賴(相當于生産者和消費者的強耦合)。萬一哪天郵差 換人了,你還要重新認識一下(相當于消費者變化導緻修改生産者代碼)。而郵筒相對 來說比較固定,你依賴它的成本就比較低(相當于和緩沖區之間的弱耦合)。

2、支援并發

由于生産者與消費者是兩個獨立的并發體,他們之間是用緩沖區作為橋梁連接配接,生産者隻需要往緩沖區裡丢資料,就可以繼續生産下一個資料,而消費者隻需要從緩沖區了拿資料即可,這樣就不會因為彼此的處理速度而發生阻塞。

接上面的例子,如果我們不使用郵筒,我們就得在郵局等郵差,直到他回來,我們把信件交給他,這期間我們啥事兒都不能幹(也就是生産者阻塞),或者郵差得挨家挨戶問,誰要寄信(相當于消費者輪詢)。

3、支援忙閑不均

緩沖區還有另一個好處。如果制造資料的速度時快時慢,緩沖區的好處就展現出來 了。當資料制造快的時候,消費者來不及處理,未處理的資料可以暫時存在緩沖區中。 等生産者的制造速度慢下來,消費者再慢慢處理掉。

為了充分複用,我們再拿寄信的例子來說事。假設郵差一次隻能帶走1000封信。 萬一某次碰上情人節(也可能是聖誕節)送賀卡,需要寄出去的信超過1000封,這時 候郵筒這個緩沖區就派上用場了。郵差把來不及帶走的信暫存在郵筒中,等下次過來 時再拿走。

實際應用

在P3版本更新項目中,資訊伺服器要接收大批量的用戶端請求,原來那種串行化的 處理,根本無法及時處理用戶端請求,造成資訊伺服器大量請求堆積,導緻丢包異 常嚴重。之後就采用了生産者消費者模式,在業務請求與業務處理間,建立了一個List 類型的緩沖區,服務端接收到業務請求,就往裡扔,然後再去接收下一個業務請求,而 多個業務處理線程,就會去緩沖區裡取業務請求處理。這樣就大大提高了伺服器的相 應速度。