Java中ArrayBlockingQueue和LinkedBlockingQueue
ArrayBlockingQueue
用數(shù)組實現(xiàn)的有界阻塞隊列。此隊列按照先進先出(FIFO)的原則對元素進行排序。默認情況下不保證訪問者公平的訪問隊列,所謂公平訪問隊列是指阻塞的所有生產(chǎn)者線程或消費者線程,當隊列可用時,可以按照阻塞的先后順序訪問隊列,即先阻塞的生產(chǎn)者線程,可以先往隊列里插入元素,先阻塞的消費者線程,可以先從隊列里獲取元素。通常情況下為了保證公平性會降低吞吐量。
LinkedBlockingQueue
基于鏈表的阻塞隊列,同ArrayListBlockingQueue類似,此隊列按照先進先出(FIFO)的原則對元素進行排序,其內(nèi)部也維持著一個數(shù)據(jù)緩沖隊列(該隊列由一個鏈表構(gòu)成),當生產(chǎn)者往隊列中放入一個數(shù)據(jù)時,隊列會從生產(chǎn)者手中獲取數(shù)據(jù),并緩存在隊列內(nèi)部,而生產(chǎn)者立即返回;只有當隊列緩沖區(qū)達到最大值緩存容量時(LinkedBlockingQueue可以通過構(gòu)造函數(shù)指定該值),才會阻塞生產(chǎn)者隊列,直到消費者從隊列中消費掉一份數(shù)據(jù),生產(chǎn)者線程會被喚醒,反之對于消費者這端的處理也基于同樣的原理。而LinkedBlockingQueue之所以能夠高效的處理并發(fā)數(shù)據(jù),還因為其對于生產(chǎn)者端和消費者端分別采用了獨立的鎖來控制數(shù)據(jù)同步,這也意味著在高并發(fā)的情況下生產(chǎn)者和消費者可以并行地操作隊列中的數(shù)據(jù),以此來提高整個隊列的并發(fā)性能。
作為開發(fā)者,我們需要注意的是,如果構(gòu)造一個LinkedBlockingQueue對象,而沒有指定其容量大小,LinkedBlockingQueue會默認一個類似無限大小的容量(Integer.MAX_VALUE),這樣的話,如果生產(chǎn)者的速度一旦大于消費者的速度,也許還沒有等到隊列滿阻塞產(chǎn)生,系統(tǒng)內(nèi)存就有可能已被消耗殆盡了。
相同:
- LinkedBlockingQueue和ArrayBlockingQueue都是可阻塞的隊列
- 內(nèi)部都是使用ReentrantLock和Condition來保證生產(chǎn)和消費的同步;
- 當隊列為空,消費者線程被阻塞;當隊列裝滿,生產(chǎn)者線程被阻塞;
- 使用Condition的方法來同步和通信:await()和signal()
不同:
1、鎖機制不同
- LinkedBlockingQueue中的鎖是分離的,生產(chǎn)者的鎖PutLock,消費者的鎖takeLock
- 而ArrayBlockingQueue生產(chǎn)者和消費者使用的是同一把鎖;
2、底層實現(xiàn)機制也不同
- LinkedBlockingQueue內(nèi)部維護的是一個鏈表結(jié)構(gòu)。
- 在生產(chǎn)和消費的時候,需要創(chuàng)建Node對象進行插入或移除,大批量數(shù)據(jù)的系統(tǒng)中,其對于GC的壓力會比較大。
- 而ArrayBlockingQueue內(nèi)部維護了一個數(shù)組
- 在生產(chǎn)和消費的時候,是直接將枚舉對象插入或移除的,不會產(chǎn)生或銷毀任何額外的對象實例。
3、構(gòu)造時候的區(qū)別
- LinkedBlockingQueue有默認的容量大小為:Integer.MAX_VALUE,當然也可以傳入指定的容量大小
- ArrayBlockingQueue在初始化的時候,必須傳入一個容量大小的值
4、執(zhí)行clear()方法
- LinkedBlockingQueue執(zhí)行clear方法時,會加上兩把鎖
5、統(tǒng)計元素的個數(shù)
- LinkedBlockingQueue中使用了一個AtomicInteger對象來統(tǒng)計元素的個數(shù),ArrayBlockingQueue則使用int類型來統(tǒng)計元素。
補充(Java些操使線程釋放鎖資源)
1.sleep()方法
在指定時間內(nèi)讓當前正在執(zhí)行的線程暫停執(zhí)行,但不會釋放“鎖標志”。不推薦使用。
sleep()使當前線程進入阻塞狀態(tài),在指定時間內(nèi)不會執(zhí)行。
2.wait()方法
在其他線程調(diào)用對象的notify或notifyAll方法前,導致當前線程等待。線程會釋放掉它所占有的“鎖標志”,從而使別的線程有機會搶占該鎖。
當前線程必須擁有當前對象鎖。如果當前線程不是此鎖的擁有者,會拋出IllegalMonitorStateException異常。
喚醒當前對象鎖的等待線程使用notify或notifyAll方法,也必須擁有相同的對象鎖,否則也會拋出IllegalMonitorStateException異常。
waite()和notify()必須在synchronized函數(shù)或synchronized block中進行調(diào)用。如果在non-synchronized函數(shù)或non-synchronized block中進行調(diào)用,雖然能編譯通過,但在運行時會發(fā)生IllegalMonitorStateException的異常。
3.yield方法
暫停當前正在執(zhí)行的線程對象。
yield()只是使當前線程重新回到可執(zhí)行狀態(tài),所以執(zhí)行yield()的線程有可能在進入到可執(zhí)行狀態(tài)后馬上又被執(zhí)行。
yield()只能使同優(yōu)先級或更高優(yōu)先級的線程有執(zhí)行的機會。
4.join方法
等待該線程終止。
等待調(diào)用join方法的線程結(jié)束,再繼續(xù)執(zhí)行。如:t.join();//主要用于等待t線程運行結(jié)束,若無此句,main則會執(zhí)行完畢,導致結(jié)果不可預測。
join()底層就是調(diào)用wait()方法的,wait()釋放鎖資源,故join也釋放鎖資源
- 1.sleep會使當前線程睡眠指定時間,不釋放鎖
- 2.yield會使當前線程重回到可執(zhí)行狀態(tài),等待cpu的調(diào)度,不釋放鎖
- 3.wait會使當前線程回到線程池中等待,釋放鎖,當被其他線程使用notify,notifyAll喚醒時進入可執(zhí)行狀態(tài)
- 4.當前線程調(diào)用 某線程.join()時會使當前線程等待某線程執(zhí)行完畢再結(jié)束,底層調(diào)用了wait,釋放鎖
到此這篇關(guān)于Java中ArrayBlockingQueue和LinkedBlockingQueue的文章就介紹到這了,更多相關(guān)Java ArrayBlockingQueue內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
- java ArrayBlockingQueue阻塞隊列的實現(xiàn)示例
- Java 并發(fā)編程ArrayBlockingQueue的實現(xiàn)
- java ArrayBlockingQueue的方法及缺點分析
- Java源碼解析阻塞隊列ArrayBlockingQueue介紹
- Java源碼解析阻塞隊列ArrayBlockingQueue常用方法
- Java源碼解析阻塞隊列ArrayBlockingQueue功能簡介
- 詳細分析Java并發(fā)集合ArrayBlockingQueue的用法
- java并發(fā)之ArrayBlockingQueue詳細介紹
- Java并發(fā)編程ArrayBlockingQueue的使用
相關(guān)文章
Spring?JPA?deleteInBatch導致StackOverflow問題
這篇文章主要介紹了Spring?JPA?deleteInBatch導致StackOverflow問題,具有很好的參考價值,希望對大家有所幫助,如有錯誤或未考慮完全的地方,望不吝賜教2024-05-05
基于SpringBoot + Android實現(xiàn)登錄功能
在移動互聯(lián)網(wǎng)的今天,許多應用需要通過移動端實現(xiàn)與服務器的交互功能,其中登錄是最常見且基礎(chǔ)的一種功能,本篇博客將詳細介紹如何使用 Spring Boot 和 Android 實現(xiàn)一個完整的登錄功能,需要的朋友可以參考下2024-11-11
spring cloud 集成 ribbon負載均衡的實例代碼
spring Cloud Ribbon 是一個客戶端的負載均衡器,它提供對大量的HTTP和TCP客戶端的訪問控制。本文給大家介紹spring cloud 集成 ribbon負載均衡,感興趣的朋友跟隨小編一起看看吧2021-11-11
Spring IOC源碼剖析_如何整體認知Spring體系結(jié)構(gòu)
這篇文章主要介紹了Spring IOC源碼剖析_如何整體認知Spring體系結(jié)構(gòu)方式,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教2021-09-09
基于Servlet實現(xiàn)技術(shù)問答網(wǎng)站系統(tǒng)
這篇文章主要為大家詳細介紹了基于Servlet實現(xiàn)技術(shù)問答網(wǎng)站系統(tǒng),具有一定的參考價值,感興趣的小伙伴們可以參考一下2017-04-04

