Java阻塞隊(duì)列BlockingQueue基礎(chǔ)與使用
什么是阻塞隊(duì)列
阻塞隊(duì)列本質(zhì)上還是一種隊(duì)列,遵循先進(jìn)先出,后進(jìn)后出的原則,在此基礎(chǔ)上,如果出隊(duì)時(shí)阻塞隊(duì)列為空,則會使當(dāng)前線程陷入阻塞,直到入隊(duì)新元素時(shí)通知線程繼續(xù)執(zhí)行,如果入隊(duì)時(shí)阻塞隊(duì)列為滿,則會使當(dāng)前線程陷入阻塞,直到出隊(duì)舊元素時(shí)才通知線程進(jìn)行執(zhí)行。
阻塞隊(duì)列的特點(diǎn)
BlockingQueue不是新的東西
學(xué)會使用隊(duì)列
阻塞隊(duì)列四組API
方式 | 拋出異常 | 有返回值,不拋出異常 | 阻塞 等待 | 超時(shí)等待 |
---|---|---|---|---|
添加 | add(E e) | offer(E e) | put() | offer(E e,Time,TimeUnit) |
移除 | remove() | poll() | take() | poll(Time,TimeUnit) |
檢測隊(duì)首元素 | element() | peek | 無 | 無 |
- 拋出異常是指當(dāng)隊(duì)列滿時(shí),再次插入會拋出異常(如果隊(duì)列未滿,插入返回值未true);
- 返回布爾是指當(dāng)隊(duì)列滿時(shí),再次插入會返回false;
- 阻塞是指當(dāng)隊(duì)列滿時(shí),再次插入會被阻塞,直到隊(duì)列取出一個(gè)元素,才能插入。
- 超時(shí)是指當(dāng)一個(gè)時(shí)限過后,才會插入或者取出。
拋出異常
/** * 拋出異常 */ public static void test1(){ // 隊(duì)列的大小 ArrayBlockingQueue blockingQueue = new ArrayBlockingQueue<>(3); System.out.println(blockingQueue.add("a")); System.out.println(blockingQueue.add("b")); System.out.println(blockingQueue.add("c")); // IllegalStateException: Queue full 拋出異常! // System.out.println(blockingQueue.add("d")); System.out.println(blockingQueue.remove()); System.out.println(blockingQueue.remove()); System.out.println(blockingQueue.remove()); // java.util.NoSuchElementException 拋出異常! // System.out.println(blockingQueue.remove()); }
有返回值,沒有異
/** * 有返回值,沒有異常 */ public static void test2(){ // 隊(duì)列的大小 ArrayBlockingQueue blockingQueue = new ArrayBlockingQueue<>(3); System.out.println(blockingQueue.offer("a")); System.out.println(blockingQueue.offer("b")); System.out.println(blockingQueue.offer("c")); // System.out.println(blockingQueue.offer("d")); // false 不拋出異常! System.out.println(blockingQueue.poll()); System.out.println(blockingQueue.poll()); System.out.println(blockingQueue.poll()); System.out.println(blockingQueue.poll()); // null 不拋出異常! }
等待,阻塞(一直阻塞)
/** * 等待,阻塞(一直阻塞) */ public static void test3() throws InterruptedException { // 隊(duì)列的大小 ArrayBlockingQueue blockingQueue = new ArrayBlockingQueue<>(3); // 一直阻塞 blockingQueue.put("a"); blockingQueue.put("b"); blockingQueue.put("c"); // blockingQueue.put("d"); // 隊(duì)列沒有位置了,一直阻塞 System.out.println(blockingQueue.take()); System.out.println(blockingQueue.take()); System.out.println(blockingQueue.take()); System.out.println(blockingQueue.take()) }
等待,阻塞(等待超時(shí)
/** * 等待,阻塞(等待超時(shí)) */ public static void test4() throws InterruptedException { // 隊(duì)列的大小 ArrayBlockingQueue blockingQueue = new ArrayBlockingQueue<>(3); blockingQueue.offer("a"); blockingQueue.offer("b"); blockingQueue.offer("c"); // blockingQueue.offer("d",2,TimeUnit.SECONDS); // 等待超過2秒就退出 System.out.println(blockingQueue.poll()); System.out.println(blockingQueue.poll()); System.out.println(blockingQueue.poll()); blockingQueue.poll(2,TimeUnit.SECONDS); }
SynchronousQueue 同步隊(duì)列
和其他的BlockingQueue 不一樣, SynchronousQueue 不存儲元素
put了一個(gè)元素,必須從里面先take取出來,否則不能在put進(jìn)去值!
public class SynchronousQueueDemo { public static void main(String[] args) { BlockingQueue<String> blockingQueue = new SynchronousQueue<>(); // 同步隊(duì) // new Thread(()->{ try { System.out.println(Thread.currentThread().getName()+" put 1"); blockingQueue.put("1"); System.out.println(Thread.currentThread().getName()+" put 2"); blockingQueue.put("2"); System.out.println(Thread.currentThread().getName()+" put 3"); blockingQueue.put("3"); } catch (InterruptedException e) { e.printStackTrace(); } },"T1").start(); new Thread(()->{ try { TimeUnit.SECONDS.sleep(3); System.out.println(Thread.currentThread().getName()+"=>"+blockingQueue.take()); TimeUnit.SECONDS.sleep(3); System.out.println(Thread.currentThread().getName()+"=>"+blockingQueue.take()); TimeUnit.SECONDS.sleep(3); System.out.println(Thread.currentThread().getName()+"=>"+blockingQueue.take()); } catch (InterruptedException e) { e.printStackTrace(); } },"T2").start(); } }
到此這篇關(guān)于Java阻塞隊(duì)列BlockingQueue基礎(chǔ)與使用的文章就介紹到這了,更多相關(guān)Java BlockingQueue內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
一文搞清楚Java中Comparable和Comparator的區(qū)別
Java中的Comparable和Comparator都是用于集合排序的接口,但它們有明顯的區(qū)別,文中通過一些實(shí)例代碼詳細(xì)介紹了Java中Comparable和Comparator的區(qū)別,感興趣的同學(xué)跟著小編一起學(xué)習(xí)吧2023-05-05詳解Spring Boot中整合Sharding-JDBC讀寫分離示例
這篇文章主要介紹了詳解Spring Boot中整合Sharding-JDBC讀寫分離示例,小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧2019-03-03Java中LinkedHashSet的實(shí)現(xiàn)原理詳解
這篇文章主要介紹了Java中LinkedHasSet的實(shí)現(xiàn)原理詳解,LinkedHashSet?是具有可預(yù)知迭代順序的?Set?接口的哈希表和鏈接列表實(shí)現(xiàn),此實(shí)現(xiàn)與HashSet?的不同之處在于,后者維護(hù)著一個(gè)運(yùn)行于所有條目的雙重鏈接列表,需要的朋友可以參考下2023-09-09SpringBoot入口類和@SpringBootApplication講解
這篇文章主要介紹了SpringBoot入口類和@SpringBootApplication講解,具有很好的參考價(jià)值,希望對大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2022-03-03Mybatis實(shí)現(xiàn)單個(gè)和批量定義別名typeAliases
這篇文章主要介紹了Mybatis實(shí)現(xiàn)單個(gè)和批量定義別名typeAliases,具有很好的參考價(jià)值,希望對大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2021-09-09