看看ConcurrentLinkedQueue源碼 in Java 9

看ConcurrentLinkedQueue這個名字,應該叫併發鏈表隊列哈。html

ConcurrentLinkedQueue是一個基於連接節點的無界線程安全隊列,它採用先進先出的規則對節點進行排序,當咱們添加一個元素的時候,它會添加到隊列的尾部,當咱們獲取一個元素時,它會返回隊列頭部的元素。算法

ConcurrentLinkedQueue由head節點和tair節點組成,每一個節點(Node)由節點元素(item)和指向下一個節點的引用(next)組成,節點與節點之間就是經過這個next關聯起來,從而組成一張鏈表結構的隊列。默認狀況下head節點存儲的元素爲空,tair節點等於head節點。安全

當許多線程共享對公共集合的訪問權限時,ConcurrentLinkedQueue是一個合適的選擇。與大多數其餘併發集合實現同樣,此類不容許使用null元素。多線程

該實現採用有效的非阻塞算法,該算法基於Maged M.Michael和Michael L.Scott提出的 Simple, Fast, and Practical Non-Blocking and Blocking Concurrent Queue Algorithms 中描述的算法。併發

迭代器是弱一致的,在迭代器建立時或以後的某個時刻返回反映隊列狀態的元素。它們不會拋出ConcurrentModificationException,而且可能與其餘操做同時進行。異步

經常使用的併發隊列有阻塞隊列和非阻塞隊列,前者使用鎖實現,後者則使用CAS非阻塞算法實現,使用非阻塞隊列通常性能比較好。性能

下面看看這個類的構造方法:this

方法的實現:線程

  • 無參的構造方法,構建一個空的ConcurrentLinkedQueue,head和tail設置爲Node(null)
  • 建立一個ConcurrentLinkedQueue,最初包含給定集合的元素,以集合迭代器的遍歷順序添加。迭代中用了Node<E> h = null, t = null;兩個變量來幫助迭代,這裏設置值用了 UNSAFE.putOrderedObject(this, nextOffset, val);

這裏要先說一下鏈表結構實現的兩個關鍵字段 head與tail,是用private transient volatile修飾:3d

能夠看到這兩個值是 Node,這個類的實現也比較關鍵。這裏有兩個屬性E item,和Node<E> next,對值得的操做用了sun.misc.Unsafe UNSAFE裏的方法實現。Node分別用來存在列表的首尾節點,其中head節點存放鏈表第一個item爲null的節點,tail則並非總指向最後一個節點。Node節點內部則維護一個變量item用來存放節點的值,next用來存放下一個節點,從而連接爲一個單向無界列表。

而後就是具體應用到相應的隊列的方法裏,好比offer方法的實現,將指定元素插入此隊列的尾部。第一是定位出尾節點,第二是使用CAS算法能將入隊節點設置成尾節點的next節點,如不成功則重試:

tail節點並不老是尾節點,因此每次入隊都必須先經過tail節點來找到尾節點,尾節點可能就是tail節點,也多是tail節點的next節點。代碼中循環體中的第一個if就是判斷tail是否有next節點,有則表示next節點多是尾節點。

而後還有poll方法的實現,檢索並刪除此隊列的頭部,若是此隊列爲空,則返回null。並非每次出隊時都更新head節點,當head節點裏有元素時,直接彈出head節點裏的元素,而不會更新head節點。只有當head節點裏沒有元素時,出隊操做纔會更新head節點:

首先獲取頭節點的元素,而後判斷頭節點元素是否爲空,若是爲空,表示另一個線程已經進行了一次出隊操做將該節點的元素取走,若是不爲空,則使用CAS的方式將頭節點的引用設置成null,若是CAS成功,則直接返回頭節點的元素,若是不成功,表示另一個線程已經進行了一次出隊操做更新了head節點,致使元素髮生了變化,須要從新獲取頭節點。

peek()方法的實現,檢索但不移除此隊列的頭部,若是此隊列爲空,則返回null。

這裏size()方法的實現,返回此隊列中的元素數。與大多數集合不一樣,size方法不是constant-time操做。因爲這些隊列的異步性質,肯定元素的當前數量須要遍歷元素,所以若是在遍歷期間修改此集合,則可能會報告不許確的結果。

還有remove方法的實現,若是隊列裏面存在該元素則刪除給元素,若是存在多個則刪除第一個,並返回true,否者返回false

發現一篇Importnew寫的不錯的博文:http://www.importnew.com/25668.html 對各類狀況還畫了圖

有什麼討論的內容,能夠加我公衆號:

相關文章
相關標籤/搜索