关于java同步包中ConcurrentLinkedQueue类的深入分析与理解
一,官方描寫(xiě)敘述
????一個(gè)基于連接節(jié)點(diǎn)的無(wú)界線程安全隊(duì)列。這個(gè)隊(duì)列的順序是先進(jìn)先出。隊(duì)列頭部的元素是留在隊(duì)列中時(shí)間最長(zhǎng)的,隊(duì)列尾部的元素是留在隊(duì)列中時(shí)間最短的。新元素被插入到元素的尾部,隊(duì)列從隊(duì)列的頭部檢索元素。當(dāng)很多線程共享訪問(wèn)同一個(gè)集合時(shí),這個(gè)類(lèi)是不二選擇。這個(gè)隊(duì)列不同意有null元素。
????這個(gè)實(shí)現(xiàn)基于一種被描寫(xiě)敘述為簡(jiǎn)單,高速,有用的非堵塞和堵塞發(fā)布隊(duì)列算法而提供的一種有效的空暇等待算法。
????注意,不像大多數(shù)集合,size方法的操作不是常量時(shí)間的,因?yàn)槭钱惒疥?duì)列,決定了元素的數(shù)量須要遍歷真?zhèn)€元素集。
????這個(gè)類(lèi)和它的迭代器實(shí)現(xiàn)了Collection和Iterator接口的全部可選方法。
二,源代碼分析
??? 例如以下代碼所看到的,這個(gè)類(lèi)繼承了AbstractQueue抽象類(lèi),實(shí)現(xiàn)了Queue和Serializable接口。
public?class?ConcurrentLinkedQueue<E>?extends?AbstractQueue<E>implements?Queue<E>,?java.io.Serializable????分析這個(gè)類(lèi)的源代碼,必須先從它的靜態(tài)內(nèi)部類(lèi)Node開(kāi)始。在Node類(lèi)中,Node的插入和比較操作都是使用底層的Unsafe類(lèi)來(lái)完畢的,也就是說(shuō),這個(gè)Node類(lèi)自身已經(jīng)是線程安全的。
????在這個(gè)類(lèi)的變量中,head和tail對(duì)象是使用volatile來(lái)修飾的,我前面的一片文章中說(shuō)過(guò),volatile是線程安全的,但不是原子操作。在這個(gè)類(lèi)中,因?yàn)槊恳粋€(gè)Node變量都是volatile修飾,因此使用指針獲取next或者previous節(jié)點(diǎn)時(shí),也是線程安全的。
????在這個(gè)類(lèi)中須要注意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的時(shí)間并非常量時(shí)間,而是O(n)時(shí)間。這也是一種以時(shí)間換取安全性的折中策略。
????在分析源代碼時(shí)你會(huì)發(fā)現(xiàn),像這個(gè)類(lèi)中得remove,peek,pool等操作中都沒(méi)有鎖或者其他持有線程安全的條件,事實(shí)上它這里的線程安全,所有都在Node靜態(tài)類(lèi)中完畢了,由于在這個(gè)源代碼中無(wú)論你用哪一個(gè)方法,事實(shí)上都是會(huì)調(diào)用Node中的next,而Node中得方法都是線程安全的,因此這些操作也都是線程安全的。
三,總結(jié)
????1,這個(gè)類(lèi)是基于隊(duì)列的鏈表,即先進(jìn)先出原則
????2.這個(gè)類(lèi)的size方法花費(fèi)O(n)時(shí)間
????3.這個(gè)類(lèi)是線程安全的,它的Iterator也是線程安全的
轉(zhuǎn)載于:https://www.cnblogs.com/mfrbuaa/p/3843441.html
總結(jié)
以上是生活随笔為你收集整理的关于java同步包中ConcurrentLinkedQueue类的深入分析与理解的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: QEMU KVM Libvirt手册(7
- 下一篇: Java虚拟机工作原理详解