java中的BlockingQueue(阻塞隊(duì)列)解析
BlockingQueue
阻塞隊(duì)列(BlockingQueue) 是一個(gè)支持兩個(gè)附加操作的隊(duì)列。這兩個(gè)附加的操作是:在隊(duì)列為空時(shí),獲取元素的線程會(huì)等待隊(duì)列變?yōu)榉强铡?/p>
當(dāng)隊(duì)列滿時(shí),存儲(chǔ)元素的線程會(huì)等待隊(duì)列可用。阻塞隊(duì)列常用于生產(chǎn)者和消費(fèi)者的場(chǎng)景,生產(chǎn)者是往隊(duì)列里添加元素的線程,消費(fèi)者是從隊(duì)列里拿元素的線程。
阻塞隊(duì)列就是生產(chǎn)者存放元素的容器,而消費(fèi)者也只從容器里拿元素。
使用場(chǎng)景: 多線程并發(fā)處理,線程池!
隊(duì)列 FIFO先進(jìn)先出 一端寫(xiě)入一端取出
寫(xiě)入如果隊(duì)列滿了就必須阻塞等待 如果隊(duì)列是空的必須阻塞等待生產(chǎn)
注意:BlockingQueue 不接受null值 試圖添加一個(gè)null元素時(shí)會(huì)拋出異常
BlockingQueue 可以是限定容量的 超過(guò)給定容量時(shí)是無(wú)法添加的
JDK中七個(gè)隊(duì)列
- ArrayBolckingQueue(常用):基于數(shù)組的有界阻塞隊(duì)列
- LinkedBlockingQueue(常用):基于鏈表的有界阻塞隊(duì)列 大小默認(rèn)為 Integer最大值
- PriorityBlockingQueue : 一個(gè)支持優(yōu)先級(jí)排序的無(wú)界阻塞隊(duì)列。
- DelayQueue: 使用優(yōu)先級(jí)隊(duì)列實(shí)現(xiàn)的延遲無(wú)界阻塞隊(duì)列
- SynchronousQueue: 一個(gè)不存儲(chǔ)元素的阻塞隊(duì)列。
- LinkedTransferQueue: 一個(gè)由鏈表結(jié)構(gòu)組成的無(wú)界阻塞隊(duì)列。
- LinkedBlockingDeque: 一個(gè)由鏈表結(jié)構(gòu)組成的雙向阻塞隊(duì)列
阻塞隊(duì)列核心方法
| 方法類(lèi)型 | 拋出異常 | 特殊值( 有返回值) | 阻塞 | 超時(shí) |
| 插入 | add | offer | put | offer |
| 移除 | remove | poll | take | poll |
| 判斷隊(duì)列首 | element | peek | - | - |
ArrayBolckingQueue使用示例
演示各個(gè)API的使用
public class Test {
public static void main(String[] args) {
test1();
}第一組會(huì)拋出異常API演示 add remove element
/**
* 拋出異常
*/
public static void test1(){
//指定隊(duì)列大小
ArrayBlockingQueue arrayBlockingQueue = new ArrayBlockingQueue<>(3);
//add添加成功返回true
System.out.println(arrayBlockingQueue.add("1"));
System.out.println(arrayBlockingQueue.add("2"));
System.out.println(arrayBlockingQueue.add("3"));
//查看隊(duì)首的元素是誰(shuí) 1
System.out.println(arrayBlockingQueue.element());
//超過(guò)隊(duì)列大小 add會(huì)拋出異常 Queue full
// System.out.println(arrayBlockingQueue.add("4"));
//remove取出一個(gè)元素 返回取出的值 如果隊(duì)列為空 remove會(huì)拋出異常
// NoSuchElementException
System.out.println(arrayBlockingQueue.remove());
System.out.println(arrayBlockingQueue.remove());
System.out.println(arrayBlockingQueue.remove());
System.out.println(arrayBlockingQueue.remove());
}
第二組API使用
public static void test1(){
//隊(duì)列的大小
ArrayBlockingQueue<Object> blockingQueue = new ArrayBlockingQueue<>(2);
//offer 添加一個(gè)元素 返回一個(gè)boolean值 成功返回true失敗返回true
System.out.println(blockingQueue.offer(1));
System.out.println(blockingQueue.offer(2));
System.out.println(blockingQueue.offer(3));
System.out.println("----------------");
//檢測(cè)隊(duì)首元素
System.out.println(blockingQueue.peek());
//poll 取出一個(gè)元素 返回一個(gè)元素 隊(duì)列為空時(shí) 取出null
System.out.println(blockingQueue.poll());
System.out.println(blockingQueue.peek());
System.out.println(blockingQueue.poll());
System.out.println(blockingQueue.poll());
}
第三組阻塞API使用
放不進(jìn)去了會(huì)一直阻塞直到有空位
/**
* 等待 一直阻塞
*/
public static void test1(){
ArrayBlockingQueue<Object> blockingQueue = new ArrayBlockingQueue<>(2);
try {
//put添加元素 沒(méi)有返回值 滿了一直阻塞
//隊(duì)列大小為二 第三個(gè)元素放不進(jìn)去 阻塞兩秒過(guò)后就會(huì)結(jié)束
blockingQueue.put("1");
blockingQueue.put("2");
blockingQueue.put("3");
} catch (InterruptedException e) {
e.printStackTrace();
}
try {
//取出元素 空了一直阻塞 返回值取出的元素
System.out.println(blockingQueue.take());;
System.out.println(blockingQueue.take());
System.out.println(blockingQueue.take());
} catch (InterruptedException e) {
e.printStackTrace();
}
}
第四組API使用
設(shè)置阻塞時(shí)間 超過(guò)阻塞時(shí)間沒(méi)放進(jìn)去就放棄等待
/**
* 等待 超時(shí)阻塞
*/
public static void test4(){
ArrayBlockingQueue<Object> blockingQueue = new ArrayBlockingQueue<>(2);
try {
//參數(shù) 插入的數(shù)值 超時(shí)時(shí)間 和 單位
blockingQueue.offer("1");
blockingQueue.offer("2");
blockingQueue.offer("3",2, TimeUnit.SECONDS);
System.out.println("------");
System.out.println(blockingQueue.poll());
System.out.println(blockingQueue.poll());
System.out.println(blockingQueue.poll(2, TimeUnit.SECONDS));
} catch (InterruptedException e) {
e.printStackTrace();
}
}
到此這篇關(guān)于java中的BlockingQueue(阻塞隊(duì)列)解析的文章就介紹到這了,更多相關(guān)BlockingQueue阻塞隊(duì)列內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
- JavaEE多線程中阻塞隊(duì)列的項(xiàng)目實(shí)踐
- Java的PriorityBlockingQueue優(yōu)先級(jí)阻塞隊(duì)列代碼實(shí)例
- Java中的SynchronousQueue阻塞隊(duì)列使用代碼實(shí)例
- Java中的SynchronousQueue阻塞隊(duì)列及使用場(chǎng)景解析
- Java中的BlockingQueue阻塞隊(duì)列原理以及實(shí)現(xiàn)詳解
- Java的非阻塞隊(duì)列ConcurrentLinkedQueue解讀
- java中阻塞隊(duì)列和非阻塞隊(duì)列的實(shí)現(xiàn)
- Java多線程實(shí)現(xiàn)阻塞隊(duì)列的示例代碼
相關(guān)文章
Spring中@Controller和@RestController的區(qū)別詳解
這篇文章主要介紹了Spring中@Controller和@RestController的區(qū)別詳解,@RestController?是?@Controller?和?@ResponseBody?的結(jié)合體,單獨(dú)使用?@RestController?的效果與?@Controller?和?@ResponseBody?二者同時(shí)使用的效果相同,需要的朋友可以參考下2023-10-10
Java8實(shí)現(xiàn)任意參數(shù)的鏈棧
這篇文章主要為大家詳細(xì)介紹了Java8實(shí)現(xiàn)任意參數(shù)的鏈棧,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2020-10-10
Java代碼中與Lua相互調(diào)用實(shí)現(xiàn)詳解
這篇文章主要為大家介紹了Java代碼中與Lua相互調(diào)用實(shí)現(xiàn)詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2022-08-08
Java實(shí)現(xiàn)Excel導(dǎo)出并添加水印
這篇文章主要為大家詳細(xì)介紹了Java如何使用poi-ooxml包導(dǎo)出xlsx添加水印,文中的示例代碼講解詳細(xì),感興趣的小伙伴可以跟隨小編一起學(xué)習(xí)一下2024-11-11
Java輕松批量替換Word文檔文字內(nèi)容的操作步驟
Word 文檔常用于撰寫(xiě)報(bào)告、合同、通知、技術(shù)文檔等,當(dāng)文檔內(nèi)容較多時(shí),如果需要修改或替換某些詞語(yǔ)、短語(yǔ),甚至是格式化文本,手動(dòng)操作往往效率很低,所以本文給大家介紹了Java實(shí)現(xiàn)輕松批量替換Word文檔文字內(nèi)容,需要的朋友可以參考下2025-09-09
微信支付java版V3驗(yàn)證數(shù)據(jù)合法性(Deom)
這篇文章主要介紹了微信支付java版V3驗(yàn)證數(shù)據(jù)合法性(Deom)的相關(guān)資料,非常不錯(cuò),具有參考借鑒價(jià)值,需要的朋友可以參考下2016-09-09
Mybatis實(shí)戰(zhàn)之TypeHandler高級(jí)進(jìn)階
本文主要介紹了自定義的枚舉TypeHandler的相關(guān)知識(shí),具有很好的參考價(jià)值,下面跟著小編一起來(lái)看下吧2017-02-02
springboot?sleuth?日志跟蹤問(wèn)題記錄
Spring?Cloud?Sleuth是一個(gè)在應(yīng)用中實(shí)現(xiàn)日志跟蹤的強(qiáng)有力的工具,使用Sleuth庫(kù)可以應(yīng)用于計(jì)劃任務(wù)?、多線程服務(wù)或復(fù)雜的Web請(qǐng)求,尤其是在一個(gè)由多個(gè)服務(wù)組成的系統(tǒng)中,這篇文章主要介紹了springboot?sleuth?日志跟蹤,需要的朋友可以參考下2023-07-07

