轉自:https://blog.csdn.net/qq_23359777/article/details/70146778
1.介紹
ArrayBlockingQueue是一個阻塞式的隊列,繼承自AbstractBlockingQueue,間接的實現了Queue接口和Collection接口。底層以數組的形式保存數據(實際上可看作一個循環數組)。常用的操作包括 add ,offer,put,remove,poll,take,peek。
前三者add offer put 是插入的操作。后面四個方法是取出的操作。他們之間的區別和關聯:
add: 內部實際上獲取的offer方法,當Queue已經滿了時,拋出一個異常。不會阻塞。
offer:當Queue已經滿了時,返回false。不會阻塞。
put:當Queue已經滿了時,會進入等待,只要不被中斷,就會插入數據到隊列中。會阻塞,可以響應中斷。
取出方法中 remove和add相互對應。也就是說,調用remove方法時,假如對列為空,則拋出一場。另外的,poll與offer相互對應。take和put相互對應。peek方法比較特殊,前三個取出的方法,都會將元素從Queue的頭部溢出,但是peek不會,實際上只是,獲取隊列頭的元素。peek方法也不會阻塞。當隊列為空時,直接返回Null。
2.對比LinkedBlockingQueue
LinkedBlockingQueue也是一個阻塞式的隊列,與ArrayBlockingQueue的區別是什么呢?
LinkedBlockingQueue保存元素的是一個鏈表。其內部有一個Node的內部類,其中有一個成員變量 Node next。就這樣形成了一個鏈表的結構,要獲取下一個元素,只要調用next就可以了。而ArrayBlockingQueue則是一個數組。
LinkedBlockingQueue內部讀寫(插入獲取)各有一個鎖,而ArrayBlockingQueue則讀寫共享一個鎖。
3.選擇LinkedBlockingQueue還是ArrayBlockingQueue
個人感覺大多數場景適合使用LinkedBlockingQueue。在JDK源碼當中有說明,LinkedBlockingQueue比ArrayBlockingQueue有更高的吞吐量,但是性能表現更難預測(也就是說相比ArrayBlockingQueue性能表現不穩定,但是也很穩定了)。
為什么會有吞吐量的區別,個人以為可能是ArrayBlockingQueue兩個鎖的緣故,在大量並發的情況下,插入和讀取都很多時,就會造成一點的時間浪費。
還有一點,應為LinkedBlockingQueue創建時,默認會直接創建一個Integer.MAX_VALUE的數組,當插入少,讀取多時,就會造成很大的空間浪費。而LinkedBlockingQueue實際上實在等需要的時候才會創建一個Node節點。