併發程式設計之併發佇列

2021-09-25 08:35:31 字數 1454 閱讀 4481

jdk 中提供了一系列場景的併發安全佇列。總的來說,按照實現方式的不同可分為阻塞佇列和非阻塞佇列,前者使用鎖實現,而後者則使用cas 非阻塞演算法實現。

1 非阻塞佇列–concurrentlinkedqueue

concurrentlinkedqueue是無界非阻塞佇列,內部使用單項鍊表實現;其中有兩個volatile 型別的node 節點分別用來存放佇列的首、尾節點。從下面的無參建構函式可知,預設頭、尾節點都是指向item為null的哨兵節點。

boolean casitem(e cmp, e val) 

void lazysetnext(nodeval)

boolean casnext(nodecmp, nodeval)

private boolean castail(nodecmp, nodeval)

private boolean cashead(nodecmp, nodeval)

以上這些方法都是保證原子性操作而實現的。由於concurrentlinkedqueue是非阻塞佇列,在新增和刪除元素時不會進行加鎖,所以對head和tail連個屬性中上加上了volatile保證了記憶體可見性,加上cas保證了原子性,從而實現了執行緒安全。

2 阻塞佇列–linkedblockingqueue

linkedblockingqueue 的內部是通過單向鍊錶實現的,使用頭、尾節點來進行入隊和

出隊操作,也就是入隊操作都是對尾節點進行操作,出隊操作都是對頭節點進行操作。

對頭、尾節點的操作分別使用了單獨的獨佔鎖從而保證了原子性,所以出隊和入隊操作是可以同時進行的。另外對頭、尾節點的獨佔鎖都配備了乙個條件佇列,用來存放被阻塞的執行緒,並結合入隊、出隊操作實現了乙個生產消費模型。

3 阻塞佇列–arrayblockingqueue

arrayblockingqueue 通過使用全域性獨佔鎖實現了同時只能有乙個執行緒進行入隊或者出隊操作,這個鎖的粒度比較大,有點類似於在方法上新增synchronized的意思。其中。他r 和poll 操作通過簡單的加鎖進行入隊、出隊操作,而put 、take 操作則使用條件變數實現了,如果佇列滿則等待,如果佇列空則等待,然後分別在出隊和入隊操作中傳送訊號啟用等待執行緒實現同步。另外,相比linkedblockingqueue,arrayblockingqueue 的size 操作的結果是精確的, 因為計算前加了全域性鎖。

4 阻塞佇列–priorityblockingqueue

priorityblockingqueue 佇列在內部使用二叉樹堆維護元素優先順序,使用陣列作為元素

儲存的資料結構,這個陣列是可擴容的。當當前元素個數》=最大容量時會通過cas 演算法擴容,出隊時始終保證出隊的元素是堆樹的根節點,而不是在佇列裡面停留時間最長的元素。使用元素的compareto 方法提供預設的元素優先順序比較規則,使用者可以自定義優先順序的比較規則。使用全域性獨佔鎖實現執行緒安全的。

併發程式設計多程序之佇列

程序彼此之間互相隔離,要實現程序間通訊 ipc multiprocessing模組支援兩種形式 佇列和管道,這兩種方式都是使用訊息傳遞的。建立佇列的類 底層就是以管道和鎖定的方式實現 queue maxsize 建立共享的程序佇列。queue是多程序安全的佇列,可以使用queue實現多程序之間的資料...

併發程式設計之AtomicReference

此類屬於原子並發包,可以對引用型別進行原子無鎖操作 構造方法 保證可見性和禁止指令重排序 private volatile v value 用給定的物件創造乙個引用原子型別 param initialvalue the initial value public atomicreference v i...

併發程式設計之程序

在python中大部分情況需要使用多程序。python提供了multiprocessing。multiprocessing模組用來開啟子程序,並在子程序中執行我們定製的任務 比如函式 該模組與多執行緒模組threading的程式設計介面類似。multiprocessing模組的功能眾多 支援子程序 ...