java并發(fā)編程工具類(lèi)JUC之LinkedBlockingQueue鏈表隊(duì)列
java.util.concurrent.LinkedBlockingQueue 是一個(gè)基于單向鏈表的、范圍任意的(其實(shí)是有界的)、FIFO阻塞隊(duì)列。訪問(wèn)與移除操作是在隊(duì)頭進(jìn)行,添加操作是在隊(duì)尾進(jìn)行,并分別使用不同的鎖進(jìn)行保護(hù),只有在可能涉及多個(gè)節(jié)點(diǎn)的操作才同時(shí)對(duì)兩個(gè)鎖進(jìn)行加鎖。
隊(duì)列是否為空、是否已滿仍然是通過(guò)元素?cái)?shù)量的計(jì)數(shù)器(count)進(jìn)行判斷的,由于可以同時(shí)在隊(duì)頭、隊(duì)尾并發(fā)地進(jìn)行訪問(wèn)、添加操作,所以這個(gè)計(jì)數(shù)器必須是線程安全的,這里使用了一個(gè)原子類(lèi) AtomicInteger,這就決定了它的容量范圍是: 1 ?Integer.MAX_VALUE。
在之前的文章中已經(jīng)為大家介紹了java并發(fā)編程的工具:BlockingQueue接口、ArrayBlockingQueue、DelayQueue。
LinkedBlockingQueue 隊(duì)列是BlockingQueue接口的實(shí)現(xiàn)類(lèi),所以它具有BlockingQueue接口的一切功能特點(diǎn)。LinkedBlockingQueue隊(duì)列 按照f(shuō)irst-in-first-out (FIFO)先進(jìn)先出的方式對(duì)元素進(jìn)行排序。LinkeBlockingQueue 提供了兩種構(gòu)造函數(shù),一個(gè)構(gòu)造函數(shù)構(gòu)造一個(gè)隊(duì)列容量為固定個(gè)數(shù)的隊(duì)列,另一個(gè)無(wú)參構(gòu)造函數(shù)構(gòu)造一個(gè)隊(duì)列容量為Integer.MAX_VALUE的隊(duì)列.
public LinkedBlockingQueue() { this(Integer.MAX_VALUE);}public LinkedBlockingQueue(int capacity) { if (capacity <= 0) throw new IllegalArgumentException(); this.capacity = capacity; last = head = new Node<E>(null);}ArrayBlockingQueue和LinkedBlockingQueue對(duì)比
ArrayBlockingQueue和LinkedBlockingQueue都是實(shí)現(xiàn)BlockingQueue接口,所以在使用方式上是一致的,下面我們就不介紹使用方法,而是從二者的性能及底層數(shù)據(jù)結(jié)構(gòu)的實(shí)現(xiàn)角度進(jìn)行
ArrayBlockingQueue插入和刪除數(shù)據(jù),只采用了一個(gè)lock鎖,讀取和寫(xiě)入操作無(wú)法并行。 所以在高并發(fā)場(chǎng)景下執(zhí)行效率會(huì)比LinkedBlockingQueue慢一些。
LinkedBlockingQueue采用“two lock queue”算法變體,雙鎖(ReentrantLock):takeLock、putLock,允許讀寫(xiě)并行,remove(e)和迭代器iterators需要獲取2個(gè)鎖。這樣可以降低線程由于線程無(wú)法獲取到lock而進(jìn)入WAITING狀態(tài)的可能性,從而提高了線程并發(fā)執(zhí)行的效率。
ArrayBlockingQueue底層代碼是采用數(shù)組實(shí)現(xiàn)的,創(chuàng)建的時(shí)候必須指定隊(duì)列的容量并分配存儲(chǔ)空間;LinkedBlockingQueue采用的是鏈表數(shù)據(jù)結(jié)構(gòu)實(shí)現(xiàn)的,其鏈表節(jié)點(diǎn)的存儲(chǔ)空間分配是動(dòng)態(tài)的,新的元素對(duì)象加入隊(duì)列分配空間,元素對(duì)象從隊(duì)列取出之后存儲(chǔ)空間GC,初始化時(shí)指定的是隊(duì)列的最大容量。但是使用鏈表數(shù)據(jù)結(jié)構(gòu)既是LinkedBlockingQueue優(yōu)勢(shì)也是它的劣勢(shì),高并發(fā)場(chǎng)景下由于空間動(dòng)態(tài)分配需要java JVM頻繁的進(jìn)行垃圾回收。
總體來(lái)說(shuō)在并發(fā)場(chǎng)景下,LinkedBlockingQueue的吞吐量比ArrayBlockingQueue更好。但是在java實(shí)現(xiàn)高性能隊(duì)列的首選是disruptor,它不是JDK自帶的。java程序員非常熟悉的Log4j2底層性能比logback和log4j有了較大的提升,究其原因就是使用了disruptor高性能隊(duì)列實(shí)現(xiàn)的異步日志
到此這篇關(guān)于java并發(fā)編程工具類(lèi)JUC之LinkedBlockingQueue鏈表隊(duì)列的文章就介紹到這了,更多相關(guān)java LinkedBlockingQueue鏈表隊(duì)列內(nèi)容請(qǐng)搜索好吧啦網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持好吧啦網(wǎng)!
相關(guān)文章:
1. 低版本IE正常運(yùn)行HTML5+CSS3網(wǎng)站的3種解決方案2. asp讀取xml文件和記數(shù)3. js的一些潛在規(guī)則使用分析4. IE6/IE7/IE8/IE9中tbody的innerHTML不能賦值的完美解決方案5. html清除浮動(dòng)的6種方法示例6. 利用CSS3新特性創(chuàng)建透明邊框三角7. XHTML 1.0:標(biāo)記新的開(kāi)端8. 詳解瀏覽器的緩存機(jī)制9. javascript xml xsl取值及數(shù)據(jù)修改第1/2頁(yè)10. html小技巧之td,div標(biāo)簽里內(nèi)容不換行
