1. 程式人生 > >java 中 阻塞佇列 非阻塞佇列 和普通佇列的區別

java 中 阻塞佇列 非阻塞佇列 和普通佇列的區別

阻塞佇列與普通佇列的區別在於,當佇列是空的時,從佇列中獲取元素的操作將會被阻塞,或者當佇列是滿時,往佇列裡新增元素的操作會被阻塞。試圖從空的阻塞佇列中獲取元素的執行緒將會被阻塞,直到其他的執行緒往空的佇列插入新的元素。同樣,試圖往已滿的阻塞佇列中新增新元素的執行緒同樣也會被阻塞,直到其他的執行緒使佇列重新變得空閒起來,如從佇列中移除一個或者多個元素,或者完全清空佇列.

1.ArrayDeque, (陣列雙端佇列) 
2.PriorityQueue, (優先順序佇列) 
3.ConcurrentLinkedQueue, (基於連結串列的併發佇列) 
4.DelayQueue, (延期阻塞佇列)(阻塞佇列實現了BlockingQueue介面) 
5.ArrayBlockingQueue, (基於陣列的併發阻塞佇列) 
6.LinkedBlockingQueue, (基於連結串列的FIFO阻塞佇列) 
7.LinkedBlockingDeque, (基於連結串列的FIFO雙端阻塞佇列) 
8.PriorityBlockingQueue, (帶優先順序的無界阻塞佇列) 
9.SynchronousQueue (併發同步阻塞佇列)

阻塞佇列和生產者-消費者模式

阻塞佇列(Blocking queue)提供了可阻塞的put和take方法,它們與可定時的offer和poll是等價的。如果Queue已經滿了,put方法會被阻塞直到有空間可用;如果Queue是空的,那麼take方法會被阻塞,直到有元素可用。Queue的長度可以有限,也可以無限;無限的Queue永遠不會充滿,所以它的put方法永遠不會阻塞。

阻塞佇列支援生產者-消費者設計模式。一個生產者-消費者設計分離了“生產產品”和“消費產品”。該模式不會發現一個工作便立即處理,而是把工作置於一個任務(“to do”)清單中,以備後期處理。生產者-消費者模式簡化了開發,因為它解除了生產者和消費者之間相互依賴的程式碼。生產者和消費者以不同的或者變化的速度生產和消費資料,生產者-消費者模式將這些活動解耦,因而簡化了工作負荷的管理。

生產者-消費者設計是圍繞阻塞佇列展開的,生產者把資料放入佇列,並使資料可用,當消費者為適當的行為做準備時會從佇列中獲取資料。生產者不需要知道消費者的省份或者數量,甚至根本沒有消費者—它們只負責把資料放入佇列。類似地,消費者也不需要知道生產者是誰,以及是誰給它們安排的工作。BlockingQueue可以使用任意數量的生產者和消費者,從而簡化了生產者-消費者設計的實現。最常見的生產者-消費者設計是將執行緒池與工作佇列相結合。

阻塞佇列簡化了消費者的編碼,因為take會保持阻塞直到可用資料出現。如果生產者不能足夠快地產生工作,讓消費者忙碌起來,那麼消費者只能一直等待,直到有工作可做。同時,put方法的阻塞特性也大大地簡化了生產者的編碼;如果使用一個有界佇列,那麼當佇列充滿的時候,生產者就會阻塞,暫不能生成更多的工作,從而給消費者時間來趕進進度。

有界佇列是強大的資源管理工具,用來建立可靠的應用程式:它們遏制那些可以產生過多工作量、具有威脅的活動,從而讓你的程式在面對超負荷工作時更加健壯。

雖然生產者-消費者模式可以把生產者和消費者的程式碼相互解耦合,但是它們的行為還是間接地通過共享佇列耦合在一起了

類庫中包含一些BlockingQueue的實現,其中LinkedBlockingQueue和ArrayBlockingQueue是FIFO佇列,與 LinkedList和ArrayList相似,但是卻擁有比同步List更好的併發效能。PriorityBlockingQueue是一個按優先順序順序排序的佇列,當你不希望按照FIFO的屬性處理元素時,這個PriorityBolckingQueue是非常有用的。正如其他排序的容器一樣,PriorityBlockingQueue可以比較元素本身的自然順序(如果它們實現了Comparable),也可以使用一個 Comparator進行排序。

最後一個BlockingQueue的實現是SynchronousQueue,它根本上不是一個真正的佇列,因為它不會為佇列元素維護任何儲存空間。不過,它維護一個排隊的執行緒清單,這些執行緒等待把元素加入(enqueue)佇列或者移出(dequeue)佇列。因為SynchronousQueue沒有儲存能力,所以除非另一個執行緒已經準備好參與移交工作,否則put和take會一直阻止。SynchronousQueue這類佇列只有在消費者充足的時候比較合適,它們總能為下一個任務作好準備。

非阻塞演算法

基於鎖的演算法會帶來一些活躍度失敗的風險。如果執行緒在持有鎖的時候因為阻塞I/O,頁面錯誤,或其他原因發生延遲,很可能所有的執行緒都不能前進了。 
一個執行緒的失敗或掛起不應該影響其他執行緒的失敗或掛起,這樣的演算法成為非阻塞(nonblocking)演算法;如果演算法的每一個步驟中都有一些執行緒能夠繼續執行,那麼這樣的演算法稱為鎖自由(lock-free)演算法。線上程間使用CAS進行協調,這樣的演算法如果能構建正確的話,它既是非阻塞的,又是鎖自由的。非競爭的CAS總是能夠成功,如果多個執行緒以一個CAS競爭,總會有一個勝出並前進。非阻塞演算法堆死鎖和優先順序倒置有“免疫性”(但它們可能會出現飢餓和活鎖,因為它們允許重進入)。

非阻塞演算法通過使用低層次的併發原語,比如比較交換,取代了鎖。原子變數類向用戶提供了這些底層級原語,也能夠當做“更佳的volatile變數”使用,同時提供了整數類和物件引用的原子化更新操作。

相關推薦

Java的NIO阻塞模式傳統的IO的阻塞模式線上程的資源消耗

       java中的NIO對於需要IO操作的程式來說,大大的提高了效率,但從NIO的實現模式來看(底層select的遍歷),因為其非阻塞的特性,犧牲了更多的系統資源,充分利用了硬體資源。      在java的網路程式設計中,少不了執行緒操作。那麼這兩種模式對系統的消耗

Java的NIO阻塞程式設計

平時工作中用到的IO主要是java.io包中的操作,比較少用到java.nio包中操作,最近遇到的比較多對效能要求較高的應用問題,查詢了一些資料整理記錄一下,方便以後檢視。 在JDK1.4以前,Java的IO操作集中在java.io這個包中,是基於流的阻塞AP

Java的記憶體分配以及棧堆的區別

Java中的記憶體分配以及棧和堆的區別 (1)棧: 存放的是區域性變數 區域性變數:在方法定義中或者方法宣告上的變數都是區域性變數。 (2)堆: 存放的是所有new出來的東西 特點: a: 每一個new出來的東西都會為其分配一個地制值。 b: 每

java 阻塞佇列 阻塞佇列 普通佇列區別

阻塞佇列與普通佇列的區別在於,當佇列是空的時,從佇列中獲取元素的操作將會被阻塞,或者當佇列是滿時,往佇列裡新增元素的操作會被阻塞。試圖從空的阻塞佇列中獲取元素的執行緒將會被阻塞,直到其他的執行緒往空的佇列插入新的元素。同樣,試圖往已滿的阻塞佇列中新增新元素的執行緒同樣也會

java 阻塞佇列 阻塞佇列 普通佇列的區別是什麼?

阻塞佇列與普通佇列的區別在於,當佇列是空的時,從佇列中獲取元素的操作將會被阻塞,或者當佇列是滿時,往佇列裡新增元素的操作會被阻塞。試圖從空的阻塞佇列中獲取元素的執行緒將會被阻塞,直到其他的執行緒往空的佇列插入新的元素。同樣,試圖往已滿的阻塞佇列中新增新元素的執行緒同樣也會

Java常用七個阻塞佇列的總結

Java佇列總結 通過前面文章的學習,我們對Java中常用佇列做了介紹。本文,咱們來對佇列做個總結吧。 首先,我們介紹了現實生活中的實際場景(排隊買票等),來告訴我們為什麼需要使用佇列。 佇列是一種先進先出(FIFO)的抽象資料結構,在Java中,佇列使用了兩種資料型別來實現的,分別是:陣列和連結串列這兩種資

java同步,非同步阻塞阻塞的聯絡區別

所謂同步就是一個任務的完成需要依賴另外一個任務時,只有等待被依賴的任務完成後,依賴的任務才能算完成,這是一種可靠的任務序列。要麼成功都成功,失敗都失敗,兩個任務的狀態可以保持一致。而非同步是不需要等待被依賴的任務完成,只是通知被依賴的任務要完成什麼工作,依賴

java併發程式設計(三)--java的鎖(Lock介面佇列同步器AQS)

public abstract class AbstractQueuedSynchronizer extends AbstractOwnableSynchronizer implements java.io.Serializable { //內部類--節點 static final clas

[Linux]阻塞阻塞(等待佇列、輪詢)機制

基本概念 阻塞指執行裝置操作時,不能獲得資源則掛起程序,被掛起的程序進入休眠,從排程器的進行佇列中移走。 非阻塞指在不能獲得資源的情況下,要麼放棄,要麼不停地查詢,直到可以操作。 等待佇列(Wait Queue) Linux 中採用等待佇列來實

JAVA IO總結 之前篇阻塞阻塞

空會叫北美廠律備具意六算高七樣任平還五元更界五程果路造海車總資條許各半變中路省小裝京地因明適據物元取她行內正示驗思以車細改壓傳命解先沒特聯算曆平量都較片種張打該那它能水基回切解專聯養路議求人交空求五觀京華青總用年品業爭快非選經處例酸滿調律技力高叫法半問設方設養示廣你每更置非即

Socket編程阻塞阻塞區別

軟件 復用 優點 調用 服務器 運用 需要 默認 con   阻塞:一般的I/O操作可以在新建的流中運用.在服務器回應前它等待客戶端發送一個空白的行.當會話結束時,服務器關閉流和客戶端socket.如果在隊列中沒有請示將會出現什麽情況呢?那個方法將會等待一個的到來.這個行為

關於veriolg阻塞阻塞賦值問題

觸發 改變 希望 到來 決定 工作 執行 為什麽 個人 在一開始學到阻塞和非阻塞的時候,所被告知的兩者的區別就在於阻塞是串行的,非阻塞是並行的。但是雖然知道這個不同點,有些時候還是很難真正區分用兩者電路的區別,在這就通過幾個例子來解釋一下。 以一個簡單的串行流水線寄存器為例

Java 同步與異步-阻塞阻塞理解

blog markdown logs 任務 一段 mar 慢操作 兩個 需要 Java 同步與異步-阻塞與非阻塞理解 Java 中同步與異步,阻塞與非阻塞都是用來形容交互方式,區別在於它們描述的是交互的兩個不同層面。 同步與異步 同步與異步更關註交互雙方是否可以同時工作。以

java nio及作業系統底層原理同步非同步阻塞阻塞

目錄 IO基本概念 同步,非同步,阻塞,非阻塞 同步與非同步 阻塞與非阻塞 IO模型(Reference Link) 阻塞I/O模型 非阻塞I/O模型 I/O複用模型 訊號驅動非同步I/O模型 非同步I/O模型 總結 AIO,BIO,NIO Jav

golangselect實現阻塞及超時控制

// select.go package main import ( "fmt" "time" //"time" ) func main() { //宣告一個channel ch := make(chan int) //宣告一個匿名函式,傳入一個引數整型

Java NIO(三)阻塞阻塞

   阻塞與非阻塞 阻塞   傳統的 IO 流都是阻塞式的。也就是說,當一個執行緒呼叫 read() 或 write()時,該執行緒被阻塞,直到有一些資料被讀取或寫入,該執行緒在此期間不能執行其他任務。因此,在完成網路通訊進行 IO 操

java】同步、非同步、阻塞阻塞

理解同步與非同步 同步是指:傳送方發出資料後,等接收方發回響應以後才發下一個數據包的通訊方式。  非同步是指:傳送方發出資料後,不等接收方發回響應,接著傳送下個數據包的通訊方式。  舉個例子:普通B/S模式(同步)    AJAX技術(非同步) 同步:提交請求->

Java網路程式設計四 阻塞通訊UDP

轉自 http://blog.csdn.net/alangdangjia/article/details/9065845 import java.io.BufferedReader;    import java.io.ByteArrayInputStream;  

網路程式設計阻塞阻塞、同步與非同步、I/O模型的理解

1. 概念理解      在進行網路程式設計時,我們常常見到同步(Sync)/非同步(Async),阻塞(Block)/非阻塞(Unblock)四種呼叫方式:同步:所謂同步,就是在發出一個功能呼叫時,在沒有得到結果之前,該呼叫就不返回。也就是必須一件一件事做,等前一件做完了才能做下一件事。 例如

Java簡單實現Socket阻塞通訊

        用java實現socket C/S通訊很簡單,很多教科書上都有。但是這些通訊模型大都是阻塞式的,其弊端也很明顯:一方必須要接收的到對方的訊息後,才能編輯自己的訊息發出。同樣對方也要一直等待這條訊息收到後才能傳送新的訊息。用網路通訊的知識講,大概就是半雙工通訊