Java阻塞隊列BlockingQueue基礎與使用
什么是阻塞隊列
阻塞隊列本質(zhì)上還是一種隊列,遵循先進先出,后進后出的原則,在此基礎上,如果出隊時阻塞隊列為空,則會使當前線程陷入阻塞,直到入隊新元素時通知線程繼續(xù)執(zhí)行,如果入隊時阻塞隊列為滿,則會使當前線程陷入阻塞,直到出隊舊元素時才通知線程進行執(zhí)行。
阻塞隊列的特點

BlockingQueue不是新的東西

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

