1- 前言
ArrayBlockingQueue是基于循環(huán)數(shù)組實現(xiàn)的有界阻塞隊列氮昧。不允許元素為null考润,構(gòu)造器內(nèi)必須指定隊列的容量燥透。
2- 定義
繼承結(jié)構(gòu)和LinkedBlockingQueue一樣卡睦,在實際使用時可以互換使用肮疗。
3- 重要字段
- item:為儲存元素的循環(huán)數(shù)組爬泥。
- takeIndex:下一次take相關(guān)操作的item數(shù)組下標(biāo)柬讨。
- putIndex:下一次put相關(guān)操作的item數(shù)組下標(biāo)。
- count:隊列元素計數(shù)袍啡。
一個ReentrantLock重入鎖踩官,兩個Condition對象。
4- 構(gòu)造器
指定初始容量(必須大于0)境输,以及鎖的公平性
調(diào)用上面構(gòu)造器蔗牡,指定初始容量,默認(rèn)設(shè)置非公平鎖
集合構(gòu)造器嗅剖,用ReentrantLock提供鎖的語義辩越,實現(xiàn)線程可見性,而不是保證線程安全信粮,因為items黔攒、count、putIndex、takeIndex都是普通變量督惰。
無論使用哪個構(gòu)造器不傅,都要指定初始大于0的容量,然后立即創(chuàng)建指定容量的Object數(shù)組赏胚,創(chuàng)建之后蛤签,就再也不能更改了,使用的循環(huán)數(shù)組來實現(xiàn)在不移動數(shù)組元素的情況下刪除添加元素到數(shù)組當(dāng)中栅哀。
5- offer方法(不響應(yīng)中斷)
加鎖入隊,保證線程安全称龙,簡單判斷一下是否隊列已滿留拾,如果已滿則直接返回false,并不等待鲫尊,然后將元素加入putIndex位置上痴柔,如果putIndex到達(dá)數(shù)組末尾則直接循環(huán)到數(shù)組頭部,因為容量不變疫向,所以不用擔(dān)心容量擴容時帶來復(fù)雜的操作咳蔚。
6- put方法(響應(yīng)中斷)
響應(yīng)中斷,并且在在隊列滿時搔驼,需要等待直到被通知notFull谈火。
7- offer(中斷超時)
8- poll(不響應(yīng)中斷)
9- take(響應(yīng)中斷)
10- poll(中斷超時)
11- peek
12- size
返回當(dāng)前隊列含有的元素數(shù)量,強一致性舌涨,時間復(fù)雜度為O(1)
13- remove
刪除第一個在隊列中出現(xiàn)的和指定對象相等的元素糯耍,時間復(fù)雜度為O(n)
14- contains
遍歷數(shù)組,時間復(fù)雜度為O(n)
15- iterator
此類 iterator() 方法每次返回的 Iterator 是一個“弱一致”的迭代器囊嘉,從不拋出 ConcurrentModificationException温技,并且確保可遍歷迭代器構(gòu)造時存在的元素扭粱,此外還可能(但并不保證)反映構(gòu)造后的所有修改舵鳞。
16- 方法列表
總結(jié)
特性基本和LinkedBlockingQueue基本一致,但是基于數(shù)組的阻塞隊列吞吐量要小于基于鏈表的阻塞隊列琢蛤。
和ArrayDeque同樣是基于循環(huán)數(shù)組實現(xiàn)的蜓堕,在ArrayDeque中是通過與數(shù)組長度length-1進(jìn)行與運算來定位元素位置的,這是因為ArrayDeque是動態(tài)擴容的虐块,而在ArrayBlockingQueue中數(shù)組是固定容量的俩滥,創(chuàng)建后不可更改,當(dāng)元素下標(biāo)超過數(shù)組長度則直接放在索引為0的位置上贺奠,這是因為count計數(shù)能保證元素數(shù)量不會超出數(shù)組的長度霜旧,當(dāng)count等于數(shù)組長度時將阻塞put元素的線程直到非空,同樣對于take元素也是類似的。
參考鏈接
http://www.importnew.com/24055.html
http://ifeve.com/juc-arrayblockingqueue/