在生產者-消費者模式中,我們常常會使用到佇列,這個佇列在多個執行緒共享訪問時存在互斥和競爭操作, 意味著每次訪問都要加鎖。如何更好的如何減少鎖競爭次數呢 ?今天要介紹的雙緩衝佇列就是個不錯的選擇。
雙緩衝佇列就是衝著同步/互斥的開銷來的。我們知道,在多個執行緒併發訪問同乙個資源的時候,需要特別注意執行緒的同步問題。稍稍不注意,噢貨,程式結果不正確了。直接上圖:
在雙緩衝佇列中,鎖除了起到保護資料安全的作用來,還要承擔執行緒排程的任務。
使用兩個訊號量,來排程入列隊和交換佇列的操作。同時,我們還需要乙個訊號量,在沒有任務入佇列時,阻塞整個消費執行緒。
主要使用 autoresetevent,manualresetevent,它們的具體使用可以看一下園子裡的文章:
autoresetevent.waitone()每次只允許乙個執行緒進入,當某個執行緒得到訊號後,autoresetevent會自動又將訊號置為不傳送狀態,則其他呼叫waitone的執行緒只有繼續等待,也就是說autoresetevent一次只喚醒乙個執行緒;我以乙個簡單的示例來演示整個過程。manualresetevent則可以喚醒多個執行緒,因為當某個執行緒呼叫了manualresetevent.set()方法後,其他呼叫waitone的執行緒獲得訊號得以繼續執行,而manualresetevent不會自動將訊號置為不傳送;
也就是說,除非手工呼叫了manualresetevent.reset()方法,則manualresetevent將一直保持有訊號狀態,manualresetevent也就可以同時喚醒多個執行緒繼續執行。
在生產線程中,入佇列一些字串;使用消費執行緒,把這些字串和它所在佇列編號列印出來:
看一下執行效果:
可以看到,在消費執行緒中,佇列交換使用。
實現乙個雙緩衝佇列
在生產者 消費者模式中,我們常常會使用到佇列,這個佇列在多個執行緒共享訪問時存在互斥和競爭操作,意味著每次訪問都要加鎖。如何更好的如何減少鎖競爭次數呢 今天要介紹的雙緩衝佇列就是個不錯的選擇。雙緩衝佇列就是衝著同步 互斥的開銷來的。我們知道,在多個執行緒併發訪問同乙個資源的時候,需要特別注意執行緒的...
Java雙緩衝佇列實現
在某一模組中,需要將網路接收到的資料存入oracle中。這是乙個典型的生產者消費者場景,可以使用訊息佇列隔離生產者和消費者。由於接收的資料頻度很高,而oracle的插入速度較慢,為不影響接收端吞吐量,選擇了雙緩衝佇列作為訊息佇列。雙緩衝佇列的原理是一般情況下生產者使用寫佇列,消費者使用讀佇列,兩個執...
雙緩衝佇列
前段時間,做了個 雙緩衝佇列 可是測試的效果就是不怎麼明顯,理論完全都在這裡,可是就是看不到效果。昨天在胡總的提示下,終於意識到不該用阻塞佇列,換成普通的list物件,這樣效果就明顯多啦 又重新寫了一篇文件,如下 好,31毫秒。這是我們的第一種解決方法,下面再來看第二種解決方法 其實我們在facto...