【高並發】不廢話,言簡意賅介紹BlockingQueue
寫在前面
最近,有不少網友留言提問:在Java的並發編程中,有個BlockingQueue,它是個阻塞隊列,為何要在並發編程里使用BlockingQueue呢?好吧,今天,就臨時說一下BlockingQueue吧,不過今天說的不是很深入,後面咱們一起從源頭上深入剖析這個類。
BlockingQueue概述
阻塞隊列,是線程安全的。
被阻塞的情況如下:
(1)當隊列滿時,進行入隊列操作
(2)當隊列空時,進行出隊列操作
使用場景如下:
主要在生產者和消費者場景。
BlockingQueue的方法
BlockingQueue 具有 4 組不同的方法用於插入、移除以及對隊列中的元素進行檢查。如果請求的操作不能得到立即執行的話,每個方法的表現也不同。這些方法如下:
拋出異常 | 特殊值 | 阻塞 | 超時 | |
---|---|---|---|---|
插入 | add(e) | offer(e) | put(e) | offer(e, time, unit) |
移除 | remove() | poll() | take() | poll(time, unit) |
檢查 | element() | peek() | 不可用 | 不可用 |
四組不同的行為方式解釋
- 拋出異常
如果試圖的操作無法立即執行,拋一個異常。
- 特殊值
如果試圖的操作無法立即執行,返回一個特定的值(常常是 true / false)。
- 阻塞
如果試圖的操作無法立即執行,該方法調用將會發生阻塞,直到能夠執行。
- 超時
如果試圖的操作無法立即執行,該方法調用將會發生阻塞,直到能夠執行,但等待時間不會超過給定值。返回一個特定值以告知該操作是否成功(典型的是 true / false)。
BlockingQueue的實現類
- ArrayBlockingQueue:有界的阻塞隊列(容量有限,必須在初始化的時候指定容量大小,容量大小指定後就不能再變化),內部實現是一個數組,以FIFO的方式存儲數據,最新插入的對象是尾部,最新移除的對象是頭部。
- DelayQueue:阻塞的是內部元素,DelayQueue中的元素必須實現一個接口——Delayed(存在於J.U.C下)。Delayed接口繼承了Comparable接口,這是因為Delayed接口中的元素需要進行排序,一般情況下,都是按照Delayed接口中的元素過期時間的優先級進行排序。應用場景主要有:定時關閉連接、緩存對象、超時處理等。內部實現使用PriorityQueue和ReentrantLock。
- LinkedBlockingQueue:大小配置是可選的,如果初始化時指定了大小,則是有邊界的;如果初始化時未指定大小,則是無邊界的(其實默認大小是Integer類型的最大值)。內部實現時一個鏈表,以FIFO的方式存儲數據,最新插入的對象是尾部,最新移除的對象是頭部。
- PriorityBlockingQueue:帶優先級的阻塞隊列,無邊界,但是有排序規則,允許插入空對象(也就是null)。所有插入的對象必須實現Comparable接口,隊列優先級的排序規則就是按照對Comparable接口的實現來定義的。可以從PriorityBlockingQueue中獲得一個迭代器Iterator,但這個迭代器並不保證按照優先級的順序進行迭代。
- SynchronousQueue:隊列內部僅允許容納一個元素,當一個線程插入一個元素後,就會被阻塞,除非這個元素被另一個線程消費。因此,也稱SynchronousQueue為同步隊列。SynchronousQueue是一個無界非緩存的隊列。準確的說,它不存儲元素,放入元素只有等待取走元素之後,才能再次放入元素。
寫在最後
如果覺得文章對你有點幫助,請微信搜索並關注「 冰河技術 」微信公眾號,跟冰河學習高並發編程技術。
最後,附上並發編程需要掌握的核心技能知識圖,祝大家在學習並發編程時,少走彎路。