Java特性隊(duì)列和棧的堵塞原理解析
做消息通信,消息會不斷從網(wǎng)絡(luò)流中取得,而后臺也有線程不斷消費(fèi)。本來我一直是使用一些線程安全標(biāo)識或方法來控制,后來在網(wǎng)上找到一些java新特性,里面包含了可以用到的堆棧使用,而且是堵塞的,這樣至少可以保證一些安全性。
對于堆:
BlockingQueue 不接受 null 元素。試圖 add、put 或 offer 一個 null 元素時,某些實(shí)現(xiàn)會拋出 NullPointerException。null 被用作指示 poll 操作失敗的警戒值。
BlockingQueue 可以是限定容量的。它在任意給定時間都可以有一個 remainingCapacity,超出此容量,便無法無阻塞地 put 附加元素。沒有任何內(nèi)部容量約束的 BlockingQueue 總是報告 Integer.MAX_VALUE 的剩余容量。
BlockingQueue 實(shí)現(xiàn)主要用于生產(chǎn)者-使用者隊(duì)列,但它另外還支持 Collection接口。因此,舉例來說,使用 remove(x) 從隊(duì)列中移除任意一個元素是有可能的。然而,這種操作通常不 會有效執(zhí)行,只能有計劃地偶爾使用,比如在取消排隊(duì)信息時。
BlockingQueue 實(shí)現(xiàn)是線程安全的。所有排隊(duì)方法都可以使用內(nèi)部鎖或其他形式的并發(fā)控制來自動達(dá)到它們的目的。然而,大量的 Collection 操作(addAll、containsAll、retainAll 和 removeAll)沒有 必要自動執(zhí)行,除非在實(shí)現(xiàn)中特別說明。因此,舉例來說,在只添加了 c 中的一些元素后,addAll(c) 有可能失敗(拋出一個異常)。
看一段代碼:
package com.test; import java.util.concurrent.ArrayBlockingQueue; import java.util.concurrent.BlockingQueue; /** * @說明 堵塞隊(duì)列和棧的使用 */ public class Test { @SuppressWarnings("unchecked") public static void main(String[] args) throws InterruptedException { BlockingQueue bqueue = new ArrayBlockingQueue(5); for (int i = 0; i < 10; i++) { // 添加元素到隊(duì)列,如果沒有可用空間,將一直等待(如果有必要) bqueue.put(i); System.out.println("添加了元素:" + i); } System.out.println("----End----"); } }
運(yùn)行效果:
添加了元素:0
添加了元素:1
添加了元素:2
添加了元素:3
添加了元素:4
之后就會一直等待。
對于棧:
BlockingDeque 方法有四種形式,使用不同的方式處理無法立即滿足但在將來某一時刻可能滿足的操作:第一種方式拋出異常;第二種返回一個特殊值(null 或 false,具體取決于操作);第三種無限期阻塞當(dāng)前線程,直至操作成功;第四種只阻塞給定的最大時間,然后放棄。
看一個例子:
package com.test; import java.util.concurrent.BlockingDeque; import java.util.concurrent.LinkedBlockingDeque; /** * @說明 堵塞隊(duì)列和棧的使用 */ public class Test { @SuppressWarnings("unchecked") public static void main(String[] args) throws InterruptedException { BlockingDeque bDeque = new LinkedBlockingDeque(5); for (int i = 0; i < 10; i++) { // 將指定元素添加到此阻塞棧中,如果沒有可用空間,將一直等待(如果有必要)。 bDeque.putFirst(i); System.out.println("添加了元素:" + i); } System.out.println("----End----"); } }
運(yùn)行結(jié)果和堆一樣,也會產(chǎn)生等待。
對于兩者的解釋:
阻塞隊(duì)列的概念是,一個指定長度的隊(duì)列,如果隊(duì)列滿了,添加新元素的操作會被阻塞等待,直到有空位為止。同樣,當(dāng)隊(duì)列為空時候,請求隊(duì)列元素的操作同樣會阻塞等待,直到有可用元素為止。
對于阻塞棧,與阻塞隊(duì)列相似。不同點(diǎn)在于棧是“后入先出”的結(jié)構(gòu),每次操作的是棧頂,而隊(duì)列是“先進(jìn)先出”的結(jié)構(gòu),每次操作的是隊(duì)列頭。
注意的是,BlockingQueue是5中的特性,jdk6以后才增加了BlockingDeque。
以上就是本文的全部內(nèi)容,希望對大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。
- Java 棧和隊(duì)列的相互轉(zhuǎn)換詳解
- Java深入了解數(shù)據(jù)結(jié)構(gòu)之棧與隊(duì)列的詳解
- Java數(shù)據(jù)結(jié)構(gòu)之棧與隊(duì)列實(shí)例詳解
- Java數(shù)據(jù)結(jié)構(gòu)專題解析之棧和隊(duì)列的實(shí)現(xiàn)
- Java數(shù)據(jù)結(jié)構(gòu)學(xué)習(xí)之棧和隊(duì)列
- 如何使用兩個棧實(shí)現(xiàn)隊(duì)列Java
- Java數(shù)據(jù)結(jié)構(gòu)之鏈表、棧、隊(duì)列、樹的實(shí)現(xiàn)方法示例
- Java編程用兩個棧實(shí)現(xiàn)隊(duì)列代碼分享
- Java棧和基礎(chǔ)隊(duì)列的實(shí)現(xiàn)詳解
相關(guān)文章
Mybatis實(shí)現(xiàn)動態(tài)SQL編寫的示例詳解
這篇文章主要為大家詳細(xì)介紹了mybatis中的動態(tài)sql的使用以及緩存的相關(guān)知識,文中的示例代碼講解詳細(xì),具有一定的學(xué)習(xí)價值,需要的可以參考一下2023-02-02IDEA利用自帶Axis工具和wsdl文件反向生成服務(wù)端客戶端代碼圖文詳解
這篇文章主要介紹了IDEA利用自帶Axis工具和wsdl文件反向生成服務(wù)端客戶端代碼詳細(xì)流程,在這里小編使用的是idea2021.1最新開發(fā)工具,本文通過圖文并茂的形式給大家介紹的非常詳細(xì),需要的朋友可以參考下2021-05-05Java中Spring MVC接收表單數(shù)據(jù)的常用方法
Spring MVC是Spring框架中的一個模塊,用于開發(fā)基于MVC(Model-View-Controller)架構(gòu)的Web應(yīng)用程序,它提供了一種輕量級的、靈活的方式來構(gòu)建Web應(yīng)用,同時提供了豐富的功能和特性,本文給大家介紹了Spring MVC接收表單數(shù)據(jù)的方法,需要的朋友可以參考下2024-05-05程序包org.springframework.boot不存在的問題解決
本文主要介紹了程序包org.springframework.boot不存在的問題解決,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2024-09-09Java中使用@CrossOrigin和Proxy解決跨域問題詳解
這篇文章主要介紹了Java中使用@CrossOrigin和Proxy解決跨域問題詳解,在Web開發(fā)中,如果前端頁面和后端接口不在同一個域名下,就會發(fā)生跨域請求的問題,同源策略是瀏覽器的一種安全策略,它限制了來自不同源的客戶端腳本在瀏覽器中運(yùn)行時的交互,需要的朋友可以參考下2023-12-12Spring boot應(yīng)用啟動后首次訪問很慢的解決方案
這篇文章主要介紹了Spring boot應(yīng)用啟動后首次訪問很慢的解決方案,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教2021-06-06