阻塞隊列java實現
『壹』 java阻塞有界隊列,需要一次添加多個元素,要麼都添加到阻塞隊列,要麼一個都不添加到阻塞隊列
就按你說的實現唄, 我看你說的挺明白的.
加入之前先判斷,隊列]空位夠不夠,夠了就加,不夠就不加
『貳』 java 阻塞隊列怎麼消費指定數據
按照個人理解,隊列就是按順序消費的數據結構,先進先出,不應該存在可以指定消費數據操作這樣的功能,一般都是你每次消費一個數據,然後判斷這個數據是不是你要消費的數據,是的話按照邏輯處理,不是的話交由另一個邏輯處理,或者拋棄不處理醬紫的。
『叄』 java的monitor機制中,為什麼阻塞隊列用list等待隊列用set
java阻塞隊列應用於生產者消費者模式、消息傳遞、並行任務執行和相關並發設計的大多數常見使用上下文。
BlockingQueue在Queue介面基礎上提供了額外的兩種類型的操作,分別是獲取元素時等待隊列變為非空和添加元素時等待空間變為可用。
BlockingQueue新增操作的四種形式:
3.2.1.3 HashMap類
對Map類的另外一個實現是HashMap。HashMap使用Hash表數據結構。HashMap假定哈希函數能夠將元素適當的分布在各桶之間,提供一種接近O(1)的查詢和更新操作。但是如果需要對集合進行迭代,則與HashMap的容量和桶的大小有關,因此HashMap的迭代效率不會很高(尤其是你為HashMap設置了較大的容量時)。
與HashMap性能有影響的兩個參數是,初始容量和載入因子。容量是哈希表中桶的數量,初始容量是哈希表在創建時的容量。載入因子是哈希表在容器容量被自動擴充之前,HashMap能夠達到多滿的一種程度。當hash表中的條目數超出了載入因子與當前容量的乘積時,Hash表需要進行rehash操作,此時Hash表將會擴充為以前兩倍的桶數,這個擴充過程需要進行完全的拷貝工作,效率並不高,因此應當盡量避免。合理的設置Hash表的初始容量和載入因子會提高Hash表的性能。HashMap自身不是線程安全的,可以通過Collections的synchronizedMap方法對HashMap進行包裝。
3.2.1.4 ConcurrentHashMap類
ConcurrentHashMap類實現了ConcurrentMap介面,並提供了與HashMap相同的規范和功能。實際上Hash表具有很好的局部可操作性,因為對Hash表的更新操作僅會影響到具體的某個桶(假設更新操作沒有引發rehash),對全局並沒有顯著影響。因此ConcurrentHashMap可以提供很好的並發處理能力。可以通過concurrencyLevel的設置,來控制並發工作線程的數目(默認為16),合理的設置這個值,有時很重要,如果這個值設置的過高,那麼很有可能浪費空間和時間,使用的值過低,又會導致線程的爭用,對數量估計的過高或過低往往會帶來明顯的性能影響。最好在創建ConcurrentHashMap時提供一個合理的初始容量,畢竟rehash操作具有較高的代價。
3.2.2 ConcurrentSkipListSet類
實際上Set和Map從結構來說是很像的,從底層的演算法原理分析,Set和Map應當屬於同源的結構。所以Java也提供了TreeSet和ConcurrentSkipListSet兩種SortedSet,分別適合於非多線程(或低並發多線程)和多線程程序使用。具體的演算法請參考前述的Map相關介紹,這里不在累述。
3.2.3 CopyOnWriteArrayList類
CopyOnWriteArrayList是ArrayList的一個線程安全的變體,其中對於所有的可變操作都是通過對底層數組進行一次新的復制來實現的。
由於可變操作需要對底層的數據進行一次完全拷貝,因此開銷一般較大,但是當遍歷操作遠遠多於可變操作時,此方法將會更有效,這是一種被稱為「快照」的模式,數組在迭代器生存期內不會發生更改,因此不會產生沖突。創建迭代器後,迭代器不會反映列表的添加、移除或者更改。不支持在迭代器上進行remove、set和add操作。CopyOnWriteArraySet與CopyOnWriteArrayList相似,只不過是Set類的一個變體。
3.2.3 Collections提供的線程安全的封裝
Collections中提供了synchronizedCollection、synchronizedList、synchronizedMap、synchronizedSet、synchronizedSortedMap、synchronizedSortedMap等方法可以完成多種集合的線程安全的包裝,如果在並發度不高的情況下,可以考慮使用這些包裝方法,不過由於Concurrent相關的類的出現,已經不這么提倡使用這些封裝了,這些方法有些人稱他們為過時的線程安全機制。
3.2.4簡單總結
提供線程安全的集合簡單概括分為三類,首先,對於並發性要求很高的需求可以選擇以Concurrent開頭的相應的集合類,這些類主要包括:ConcurrentHashMap、ConcurrentLinkedQueue、ConcurrentSkipListMap、ConcurrentSkipSet。其次對於可變操作次數遠遠小於遍歷的情況,可以使用CopyOnWriteArrayList和CopyOnWriteArraySet類。最後,對於並發規模比較小的並行需求可以選擇Collections類中的相應方法對已有集合進行封裝。
此外,本章還對一些集合類的底層實現進行簡單探討,對底層實現的了解有利於對何時使用何種方式作出正確判斷。希望大家能夠將涉及到原理(主要有循環隊列、堆、HashMap、紅黑樹、SkipList)進行仔細研究,這樣才能更深入了解Java為什麼這樣設計類庫,在什麼情況使用,應當如何使用。
『肆』 java 中 阻塞隊列 非阻塞隊列 和普通隊列的區別是什麼
阻塞隊列與普通隊列的區別在於,當隊列是空的時,從隊列中獲取元素的操作將會被阻塞,或者當隊列是滿時,往隊列里添加元素的操作會被阻塞。試圖從空的阻塞隊列中獲取元素的線程將會被阻塞,直到其他的線程往空的隊列插入新的元素。同樣,試圖往已滿的阻塞隊列中添加新元素的線程同樣也會被阻塞,直到其他的線程使隊列重新變得空閑起來,如從隊列中移除一個或者多個元素,或者完全清空隊列.
從5.0開始,JDK在java.util.concurrent包里提供了阻塞隊列的官方實現。盡管JDK中已經包含了阻塞隊列的官方實現,但是熟悉其背後的原理還是很有幫助的。一下是阻塞隊列的實現:
publicclassBlockingQueue{
privateListqueue=newLinkedList();
privateintlimit=10;
publicBlockingQueue(intlimit){
this.limit=limit;
}
publicsynchronizedvoidenqueue(Objectitem)
throwsInterruptedException{
while(this.queue.size()==this.limit){
wait();
}
if(this.queue.size()==0){
notifyAll();
}
this.queue.add(item);
}
()
throwsInterruptedException{
while(this.queue.size()==0){
wait();
}
if(this.queue.size()==this.limit){
notifyAll();
}
returnthis.queue.remove(0);
}
}
『伍』 java中的隊列都有哪些,有什麼區別
阻塞隊列、普通隊列,非阻塞隊列。
阻塞隊列與普通隊列的而區別在於,當隊列是空時,從隊列中獲取元素的操作會被阻塞,或則當隊列是滿的時,往隊列中增加元素會被阻塞,試圖從空的隊列中取元素的線程或從滿的隊列中添加元素的線程同樣會被阻塞。
『陸』 queue java 是怎麼實現的
java中queue的使用
Queue介面與List、Set同一級別,都是繼承了Collection介面。LinkedList實現了Queue接 口。Queue介面窄化了對LinkedList的方法的訪問許可權(即在方法中的參數類型如果是Queue時,就完全只能訪問Queue介面所定義的方法 了,而不能直接訪問 LinkedList的非Queue的方法),以使得只有恰當的方法才可以使用。BlockingQueue 繼承了Queue介面。
隊列是一種數據結構.它有兩個基本操作:在隊列尾部加人一個元素,和從隊列頭部移除一個元素就是說,隊列以一種先進先出的方式管理數據,如果你試圖向一個 已經滿了的阻塞隊列中添加一個元素或者是從一個空的阻塞隊列中移除一個元索,將導致線程阻塞.在多線程進行合作時,阻塞隊列是很有用的工具。工作者線程可 以定期地把中間結果存到阻塞隊列中而其他工作者線線程把中間結果取出並在將來修改它們。隊列會自動平衡負載。如果第一個線程集運行得比第二個慢,則第二個 線程集在等待結果時就會阻塞。如果第一個線程集運行得快,那麼它將等待第二個線程集趕上來。下表顯示了jdk1.5中的阻塞隊列的操作:
add 增加一個元索 如果隊列已滿,則拋出一個IIIegaISlabEepeplian異常
remove 移除並返回隊列頭部的元素 如果隊列為空,則拋出一個NoSuchElementException異常
element 返回隊列頭部的元素 如果隊列為空,則拋出一個NoSuchElementException異常
offer 添加一個元素並返回true 如果隊列已滿,則返回false
poll 移除並返問隊列頭部的元素 如果隊列為空,則返回null
peek 返回隊列頭部的元素 如果隊列為空,則返回null
put 添加一個元素 如果隊列滿,則阻塞
take 移除並返回隊列頭部的元素 如果隊列為空,則阻塞
remove、element、offer 、poll、peek 其實是屬於Queue介面。
阻塞隊列的操作可以根據它們的響應方式分為以下三類:aad、removee和element操作在你試圖為一個已滿的隊列增加元素或從空隊列取得元素時 拋出異常。當然,在多線程程序中,隊列在任何時間都可能變成滿的或空的,所以你可能想使用offer、poll、peek方法。這些方法在無法完成任務時 只是給出一個出錯示而不會拋出異常。
注意:poll和peek方法出錯進返回null。因此,向隊列中插入null值是不合法的。
還有帶超時的offer和poll方法變種,例如,下面的調用:
boolean success = q.offer(x,100,TimeUnit.MILLISECONDS);
嘗試在100毫秒內向隊列尾部插入一個元素。如果成功,立即返回true;否則,當到達超時進,返回false。同樣地,調用:
Object head = q.poll(100, TimeUnit.MILLISECONDS);
如果在100毫秒內成功地移除了隊列頭元素,則立即返回頭元素;否則在到達超時時,返回null。
最後,我們有阻塞操作put和take。put方法在隊列滿時阻塞,take方法在隊列空時阻塞。
java.ulil.concurrent包提供了阻塞隊列的4個變種。默認情況下,LinkedBlockingQueue的容量是沒有上限的(說的不準確,在不指定時容量為Integer.MAX_VALUE,不要然的話在put時怎麼會受阻呢),但是也可以選擇指定其最大容量,它是基於鏈表的隊列,此隊列按 FIFO(先進先出)排序元素。
ArrayBlockingQueue在構造時需要指定容量, 並可以選擇是否需要公平性,如果公平參數被設置true,等待時間最長的線程會優先得到處理(其實就是通過將ReentrantLock設置為true來 達到這種公平性的:即等待時間最長的線程會先操作)。通常,公平性會使你在性能上付出代價,只有在的確非常需要的時候再使用它。它是基於數組的阻塞循環隊 列,此隊列按 FIFO(先進先出)原則對元素進行排序。
PriorityBlockingQueue是一個帶優先順序的 隊列,而不是先進先出隊列。元素按優先順序順序被移除,該隊列也沒有上限(看了一下源碼,PriorityBlockingQueue是對 PriorityQueue的再次包裝,是基於堆數據結構的,而PriorityQueue是沒有容量限制的,與ArrayList一樣,所以在優先阻塞 隊列上put時是不會受阻的。雖然此隊列邏輯上是無界的,但是由於資源被耗盡,所以試圖執行添加操作可能會導致 OutOfMemoryError),但是如果隊列為空,那麼取元素的操作take就會阻塞,所以它的檢索操作take是受阻的。另外,往入該隊列中的元 素要具有比較能力。
最後,DelayQueue(基於PriorityQueue來實現的)是一個存放Delayed 元素的無界阻塞隊列,只有在延遲期滿時才能從中提取元素。該隊列的頭部是延遲期滿後保存時間最長的 Delayed 元素。如果延遲都還沒有期滿,則隊列沒有頭部,並且poll將返回null。當一個元素的 getDelay(TimeUnit.NANOSECONDS) 方法返回一個小於或等於零的值時,則出現期滿,poll就以移除這個元素了。此隊列不允許使用 null 元素。
『柒』 java什麼是阻塞隊列 非阻塞隊列
阻塞隊列與普通隊列的區別在於,當隊列是空的時,從隊列中獲取元素的操作將會被阻塞,或者當隊列是滿時,往隊列里添加元素的操作會被阻塞。試圖從空的阻塞隊列中獲取元素的線程將會被阻塞,直到其他的線程往空的隊列插入新的元素。同樣,試圖往已滿的阻塞隊列中添加新元素的線程同樣也會被阻塞,直到其他的線程使隊列重新變得空閑起來,如從隊列中移除一個或者多個元素,或者完全清空隊列.
從5.0開始,JDK在java.util.concurrent包里提供了阻塞隊列的官方實現。盡管JDK中已經包含了阻塞隊列的官方實現,但是熟悉其背後的原理還是很有幫助的。一下是阻塞隊列的實現:
public class BlockingQueue {
private List queue = new LinkedList();
private int limit = 10;
public BlockingQueue(int limit){
this.limit = limit;
}
public synchronized void enqueue(Object item)
throws InterruptedException {
while(this.queue.size() == this.limit) {
wait();
}
if(this.queue.size() == 0) {
notifyAll();
}
this.queue.add(item);
}
public synchronized Object dequeue()
throws InterruptedException{
while(this.queue.size() == 0){
wait();
}
if(this.queue.size() == this.limit){
notifyAll();
}
return this.queue.remove(0);
}
}
http://..com/link?url=sfWg_--pIZTP9i9plB7AvEDTUgG3m
『捌』 java中如何對某個方法或者某個代碼塊使用阻塞隊列來保證並發情況下線程是安全的
synchronize加在函數方法或者代碼塊,就能按你說的保證線程安全,原理是多線程進入時候系統會只允許一個線程執行那些語句
『玖』 到底什麼是消息隊列Java中如何實現消息隊列
「消息隊列」是在消息的傳輸過程中保存消息的容器。和我們學過的LinkedHashMap,TreeSet等一樣,都是容器。既然是容器,就有有自己的特性,就像LinkedHashMap是以鍵值對存儲。存取順序不變。而消息隊列,看到隊列就可以知道。這個容器裡面的消息是站好隊的,一般遵從先進先出原則。
java中已經為我們封裝好了很多的消息隊列。在java 1.5版本時推出的java.util.concurrent中有很多現成的隊列供我們使用。特性繁多,種類齊全。是你居家旅遊開發必備QAQ。
下面簡單列舉這個包中的消息隊列
:阻塞隊列 BlockingQueue
數組阻塞隊列 ArrayBlockingQueue
延遲隊列 DelayQueue
鏈阻塞隊列 LinkedBlockingQueue
具有優先順序的阻塞隊列 PriorityBlockingQueue
同步隊列 SynchronousQueue
阻塞雙端隊列 BlockingDeque
鏈阻塞雙端隊列 LinkedBlockingDeque
不同的隊列不同的特性決定了隊列使用的時機,感興趣的話你可以詳細了解。具體的使用方式我就不贅述了
『拾』 「每天一道面試題」Java中的阻塞隊列有哪些
Java里的阻塞隊列有以下幾種:
ArrayBlockingQueue :一個由數組結構組成的有界阻塞隊列。
LinkedBlockingQueue :一個由鏈表結構組成的有界阻塞隊列。
PriorityBlockingQueue :一個支持優先順序排序的無界阻塞隊列。
DelayQueue:一個使用優先順序隊列實現的無界阻塞隊列。
SynchronousQueue:一個不存儲元素的阻塞隊列。
LinkedTransferQueue:一個由鏈表結構組成的無界阻塞隊列。
LinkedBlockingDeque:一個由鏈表結構組成的雙向阻塞隊列。