乙個生產 消費者問題

2022-02-20 20:53:09 字數 1436 閱讀 6013

這幾天在寫乙個小工具,其核心就是乙個生產消費者問題

1. 單個生產者生產資料d

2. 多個一級消費者併發消費資料d,得到d'

3. 單個二級消費者消費d',此處有一額外限定:d'不能立即被消費,必須在一定延時之後才能被消費

4. 資料是有限的,資料被消費完畢之後,程式必須停止

我的思考過程如下

1. 不考慮二級消費者,只考慮單個生產者多個消費者的情況

最標準的生產消費者問題,只需要使用blockingqueue即可,生產者將資料put到佇列,消費者從佇列中take資料。

由於生產者速度極快,為了防止佇列無限增長引起oom,實際採用的是linkedblockingqueue,佇列寫滿後,put操作會被阻塞

為了讓程式能在資料處理完畢(是否處理完畢只有生產者知道)之後結束,生產者會在資料處理完畢之後,向佇列中放入和消費者數量等同的毒丸物件,消費者讀到毒丸物件之後就會自殺。這樣生產者+消費者執行緒都能正常結束。

2. 考慮二級消費者,和延時消費的設定

為了滿足延時消費,我使用了delayqueue,因為放入delayqueue中的元素只有在經過了設定的時間後才能被取出。

此時一級消費者同時也是生產者,一級消費者會將自己處理完畢的資料打上時間標記,然後寫入到delayqueue中,二級消費者從delayqueue中讀取資料。

為了保證程式能在資料處理完畢後結束,我設計了這樣的機制:

一級消費者會在讀到毒丸物件後,向二級消費者同樣寫入乙個毒丸物件。

二級消費者會統計接收到的毒丸物件的數量n,如果n==一級消費者的總數,說明所有一級消費者均已死亡,也就是說delayqueue不會再被寫入新的資料。

此時如果delayqueue長度為0,表示所有資料均已消費完畢,二級消費者執行緒亦可自殺。

在將思路轉換為實際**的過程中,還是遇到了很多麻煩

1. delayqueue的元素必須要實現delay介面,那麼也必須要實現getdelay和compareto方法。

其中特別需要注意的是getdelay方法,這個方法有乙個timeunit型別的引數,返回值代表這個物件還有多久到期。

我最開始認為這個方法與compareto類似,返回結果只要是個正負數就行,具體數字無所謂。於是我就直接無視傳入的timeunit引數,直接以毫秒為單位返回結果。但是實際上這樣做是有問題的:

分析delayqueue的原始碼後發現,delayqueue內部維護了乙個優先佇列(根據過載的compareto方法進行排序),從佇列中取元素的時候,delayqueue會呼叫隊頭的元素的getdelay方法(傳入的timeunit引數是nanoseconds!),然後根據返回結果呼叫awaitnanos方法等待一定的時間。從這裡我們可以看出,按我的做法,delayqueue的檢查頻率會提公升若干個數量級,白白耗費cpu資源。

總之,編寫乙個能正確工作的多執行緒程式是很困難的

乙個生產者和乙個消費者

我想開發乙個可以允許最多有3個物品的 生產者 消費者 例子 說明的是生產者,消費者都只有乙個 1。代表商店店員 public class clerk catch interruptedexception e this.product system.out.printf 現在共有商品 d n個 thi...

使用乙個mutex解決生產者消費者問題

好吧.乙個mutex 只能解決 乙個生產者,乙個消費者的情況 生產消費 具體是這樣的,2個執行緒同時啟動,生產線程比如在陣列中放入乙個值,然後通知消費執行緒,消費執行緒幹完事後再通知生產者.消費者的核心是 俺永遠只能跟在生產者屁股後面 使用乙個mutex 實現 當然 只用乙個mutex 只能讓執行緒...

生產消費者

producer consumer model include include define buffer size 100 緩衝區數量 define max seq 200 define n consumer 10 消費者數量 define n producer 3 生產者數量 define t ...