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 Cloud使用Feign進行遠程調(diào)用的操作指南
本文介紹了Feign作為聲明式HTTP客戶端在SpringCloud中的使用,從簡介、對比RestTemplate的問題、使用步驟,到日志配置、性能優(yōu)化和實際應(yīng)用進行了詳細講解,包括如何通過Feign簡化接口調(diào)用,以及解決啟動時找不到FeignClient的問題,需要的朋友可以參考下2025-02-02
Java關(guān)鍵字final的實現(xiàn)原理分析
這篇文章主要介紹了Java關(guān)鍵字final的實現(xiàn)原理分析,在JDK8之前,如果在匿名內(nèi)部類中需要訪問局部變量,那么這個局部變量一定是final修飾的,但final關(guān)鍵字可以省略,需要的朋友可以參考下2024-01-01
application.yml文件中如何開啟mybatis自動駝峰映射
這篇文章主要介紹了application.yml文件中開啟mybatis自動駝峰映射的方法,本文通過示例代碼給大家介紹的非常詳細,對大家的學(xué)習(xí)或工作具有一定的參考借鑒價值,需要的朋友可以參考下2023-08-08
Java實現(xiàn)大文件的分片上傳與下載(springboot+vue3)
這篇文章主要為大家詳細介紹了java基于springboot+vue3如何大文件的分片上傳與下載,文中示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下2023-06-06
tio-boot?jfinal-plugins框架整合redis示例詳解
這篇文章主要為大家介紹了tio-boot?jfinal-plugins框架整合redis示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪2023-12-12
Java?數(shù)據(jù)結(jié)構(gòu)與算法系列精講之單向鏈表
單向鏈表特點是鏈表的鏈接方向是單向的,訪問要通過順序讀取從頭部開始。鏈表是使用指針構(gòu)造的列表,是由一個個結(jié)點組裝起來的,又稱為結(jié)點列表。其中每個結(jié)點都有指針成員變量指向列表中的下一個結(jié)點,head指針指向第一個結(jié)點稱為表頭,而終止于最后一個指向nuLL的指針2022-02-02
java線程Thread.sleep()對比對象的wait示例解析
這篇文章主要為大家介紹了java線程Thread.sleep()對比對象的wait示例解析,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪2023-09-09

