Java阻塞隊列必看類:BlockingQueue快速了解大體框架和實現(xiàn)思路
前言
本文主要說明BlockingQueue類、阻塞隊列使用的共同父類AbstractQueue的基礎(chǔ)知識。后續(xù)將會逐漸探索BlockingQueue的所有實現(xiàn)類。
BlockingQueue
概覽
1. 不接受null元素。
通過新增方法添加null元素時,會拋出空指針異常。因為null值將用作標記??值,來指明poll操作失敗。同時null值作為阻塞隊列的元素也是無任何意義的。
2. 可以有容量限制,也可以沒有。
當(dāng)作為有界隊列時,如果當(dāng)隊列空間不足時,add操作將會拋出IllegalStateException異常,offer將會返回false,put操作將會阻塞直到隊列空間可用。
如果不設(shè)置容量大小,那么默認值是Integer.MAX_VALUE。此時可以看作無界隊列;
雖然隊列在邏輯上可以是無界的,但由于資源耗盡(導(dǎo)致OutOfMemoryError ),添加操作可能會失敗。
3. 用于生產(chǎn)者-消費者隊列,但是同時也支持Collection的操作。
例如刪除隊列元素操作remove(e),但是這些操作的效率很低,一般僅用于刪除某個臨時取消的任務(wù)。
4. 所有實現(xiàn)都是線程安全的。
但是對于集合中的批量操作方法,如果其實現(xiàn)類沒有特殊處理的話,那么addAll、containsAll、retainAll、removeAll等可能不會原子地執(zhí)行。
5. 隊列,整體上都基本準尋先進先出的訪問順序。
在整體上看,各個實現(xiàn)類是符合FIFO的順序的。
主要實現(xiàn)類
LinkedBlockingQueue
:鏈表式阻塞隊列ArrayBlockingQueue
:數(shù)組式阻塞隊列PriorityBlockingQueue
:優(yōu)先級阻塞隊列LinkedBlockingDeque
:阻塞型雙端隊列DelayQueue
:延時阻塞隊列SynchronousQueue
:實時同步隊列(沒有任何存儲元素的空間)- …………
BlockingQueue方法的四類形式
BlockingQueue的所有實現(xiàn)類的方法都分為如下四類。相對于其他的集合操作方法,put和take是實現(xiàn)阻塞操作的核心方法,需要重點關(guān)注。
Throws exception
:操作未實現(xiàn)時(正常流程下的執(zhí)行)拋出異常Special value
:根據(jù)操作的實際情況,返回特定值,例如null、falseBlocks
:阻塞當(dāng)前線程,直到當(dāng)前線程可以成功執(zhí)行Times out
:嘗試指定時間后,放棄執(zhí)行
Throws exception | Special value | Blocks | Times out | |
新增 | add(E e) | offer(E e) | put(E e) | offer(E e, long timeout, TimeUnit unit) |
刪除 | remove() | poll() | take() | poll(long timeout, TimeUnit unit) |
查詢 | element() | peek() |
BlockingQueue類確定了阻塞隊列的整體框架,確定了各個方法的定義,因此也是了解阻塞隊列一定要學(xué)習(xí)的類。
本文中大部分都是從源碼注釋中解讀而來,同時也包含了一些自己的理解,如果表述有誤,還望指出。
AbstractQueue
概覽
AbstractQueue類,提供了一些Queue操作的骨架實現(xiàn)。
這里提及AbstractQueue的原因是,阻塞隊列的大多實現(xiàn)類都繼承該類,可以說,這個抽象類,實現(xiàn)了BlockingQueue的大部分通用功能。比如add、remove失敗時拋出異常等等,下面會一一提及。
源碼解析
這個類基本上搭建起了一個阻塞隊列Throws exception形式的框架,它實現(xiàn)了各個拋出異常的方法。
各個方法都比較簡單,關(guān)鍵在于了解其具體的實現(xiàn)思路。這對了解各個阻塞隊列的實現(xiàn)類很有幫助。
add
? ? public boolean add(E e) { ? ? ? ? if (offer(e)) ? ? ? ? ? ? return true; ? ? ? ? else ? ? ? ? ? ? throw new IllegalStateException("Queue full"); ? ? }
當(dāng)隊列空間足夠時,將直接插入成功。offer方法由具體的子類實現(xiàn)。
如果offer插入元素成功,則add返回true ,否則將拋出IllegalStateException異常。
remove
? ? public E remove() { ? ? ? ? E x = poll(); ? ? ? ? if (x != null) ? ? ? ? ? ? return x; ? ? ? ? else ? ? ? ? ? ? throw new NoSuchElementException(); ? ? }
檢索并刪除隊列的隊首元素。
它與poll不同之處僅在于,如果此隊列為空,它會拋出NoSuchElementException異常。
刪除成功后,返回刪除的元素。
element
? ? public E element() { ? ? ? ? E x = peek(); ? ? ? ? if (x != null) ? ? ? ? ? ? return x; ? ? ? ? else ? ? ? ? ? ? throw new NoSuchElementException(); ? ? }
僅獲取隊列的隊首元素并返回結(jié)果,并不進行操作。
與peek不同之處在于,如果此隊列為空,它會引發(fā)NoSuchElementException異常。
clear
與addAll
? ? public void clear() { ? ? ? ? while (poll() != null) ? ? ? ? ? ? ; ? ? }? ? ? ? public boolean addAll(Collection<? extends E> c) { ? ? ? ? if (c == null) ? ? ? ? ? ? throw new NullPointerException(); ? ? ? ? if (c == this) ? ? ? ? ? ? throw new IllegalArgumentException(); ? ? ? ? boolean modified = false; ? ? ? ? for (E e : c) ? ? ? ? ? ? if (add(e)) ? ? ? ? ? ? ? ? modified = true; ? ? ? ? return modified; ? ? }
遍歷添加或刪除所有元素,實現(xiàn)挺簡單的,不過這里并沒有進行單個操作出現(xiàn)異常時的處理。
總結(jié)
阻塞隊列了解得也差不多了,之前只是簡單的學(xué)習(xí)了如何使用阻塞隊列的方法,這次也是打算來一個全面深入的學(xué)習(xí)吧。知其然知其所以然,對于程序員還是蠻重要的。
以上為個人經(jīng)驗,希望能給大家一個參考,也希望大家多多支持腳本之家。
- 關(guān)于Java中阻塞隊列BlockingQueue的詳解
- Java阻塞隊列BlockingQueue基礎(chǔ)與使用
- Java阻塞隊列BlockingQueue詳解
- Java?阻塞隊列BlockingQueue詳解
- Java并發(fā)編程之阻塞隊列(BlockingQueue)詳解
- Java源碼解析阻塞隊列ArrayBlockingQueue介紹
- Java源碼解析阻塞隊列ArrayBlockingQueue常用方法
- Java源碼解析阻塞隊列ArrayBlockingQueue功能簡介
- 詳解Java阻塞隊列(BlockingQueue)的實現(xiàn)原理
- java 中 阻塞隊列BlockingQueue詳解及實例
- 一文簡介Java中BlockingQueue阻塞隊列
相關(guān)文章
Spring中@ExceptionHandler注解的工作原理詳解
這篇文章主要介紹了Spring中@ExceptionHandler注解的工作原理詳解,Spring Web注解@ExceptionHandler可以用來指定處理某類異常的控制器方法,從而在這些異常發(fā)生時,會有相應(yīng)的控制器方法來處理此類異常,需要的朋友可以參考下2024-01-01SpringBoot整合Javamail實現(xiàn)郵件發(fā)送的詳細過程
日常開發(fā)過程中,我們經(jīng)常需要使用到郵件發(fā)送任務(wù),比方說驗證碼的發(fā)送、日常信息的通知等,下面這篇文章主要給大家介紹了關(guān)于SpringBoot整合Javamail實現(xiàn)郵件發(fā)送的詳細過程,需要的朋友可以參考下2022-10-10java使用CompletableFuture分批處理任務(wù)實現(xiàn)
本文主要介紹了java使用CompletableFuture分批處理任務(wù)實現(xiàn),文中通過示例代碼介紹的非常詳細,對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2024-07-07SpringBoot多數(shù)據(jù)庫連接(mysql+oracle)的實現(xiàn)
這篇文章主要介紹了SpringBoot多數(shù)據(jù)庫連接(mysql+oracle)的實現(xiàn),文中通過示例代碼介紹的非常詳細,對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2021-03-03SpringBoot如何接收Post請求Body里面的參數(shù)
這篇文章主要介紹了SpringBoot如何接收Post請求Body里面的參數(shù),具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教2022-03-03SpringBoot Shiro配置自定義密碼加密器代碼實例
這篇文章主要介紹了SpringBoot Shiro配置自定義密碼加密器代碼實例,文中通過示例代碼介紹的非常詳細,對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友可以參考下2020-03-03