关于java同步包中ConcurrentLinkedQueue类的深入分析与理解
一,官方描寫敘述
????一個基于連接節點的無界線程安全隊列。這個隊列的順序是先進先出。隊列頭部的元素是留在隊列中時間最長的,隊列尾部的元素是留在隊列中時間最短的。新元素被插入到元素的尾部,隊列從隊列的頭部檢索元素。當很多線程共享訪問同一個集合時,這個類是不二選擇。這個隊列不同意有null元素。
????這個實現基于一種被描寫敘述為簡單,高速,有用的非堵塞和堵塞發布隊列算法而提供的一種有效的空暇等待算法。
????注意,不像大多數集合,size方法的操作不是常量時間的,因為是異步隊列,決定了元素的數量須要遍歷真個元素集。
????這個類和它的迭代器實現了Collection和Iterator接口的全部可選方法。
二,源代碼分析
??? 例如以下代碼所看到的,這個類繼承了AbstractQueue抽象類,實現了Queue和Serializable接口。
public?class?ConcurrentLinkedQueue<E>?extends?AbstractQueue<E>implements?Queue<E>,?java.io.Serializable????分析這個類的源代碼,必須先從它的靜態內部類Node開始。在Node類中,Node的插入和比較操作都是使用底層的Unsafe類來完畢的,也就是說,這個Node類自身已經是線程安全的。
????在這個類的變量中,head和tail對象是使用volatile來修飾的,我前面的一片文章中說過,volatile是線程安全的,但不是原子操作。在這個類中,因為每一個Node變量都是volatile修飾,因此使用指針獲取next或者previous節點時,也是線程安全的。
????在這個類中須要注意size方法,源碼例如以下:
????
public?int?size()?{int?count?=?0;for?(Node<E>?p?=?first();?p?!=?null;?p?=?succ(p))if?(p.item?!=?null)//?Collection.size()?spec?says?to?max?outif?(++count?==?Integer.MAX_VALUE)break;return?count;}????從以上源碼能夠看出,獲取size的時間并非常量時間,而是O(n)時間。這也是一種以時間換取安全性的折中策略。
????在分析源代碼時你會發現,像這個類中得remove,peek,pool等操作中都沒有鎖或者其他持有線程安全的條件,事實上它這里的線程安全,所有都在Node靜態類中完畢了,由于在這個源代碼中無論你用哪一個方法,事實上都是會調用Node中的next,而Node中得方法都是線程安全的,因此這些操作也都是線程安全的。
三,總結
????1,這個類是基于隊列的鏈表,即先進先出原則
????2.這個類的size方法花費O(n)時間
????3.這個類是線程安全的,它的Iterator也是線程安全的
轉載于:https://www.cnblogs.com/mfrbuaa/p/3843441.html
總結
以上是生活随笔為你收集整理的关于java同步包中ConcurrentLinkedQueue类的深入分析与理解的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: QEMU KVM Libvirt手册(7
- 下一篇: 如何判断一个点是否在一个多边形内?