日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程语言 > java >内容正文

java

Java并发包--阻塞队列(BlockingQueue)

發布時間:2024/4/13 java 65 豆豆
生活随笔 收集整理的這篇文章主要介紹了 Java并发包--阻塞队列(BlockingQueue) 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

阻塞隊列介紹

在新增的Concurrent包中,BlockingQueue很好的解決了多線程中,如何高效安全“傳輸”數據的問題。通過這些高效并且線程安全的隊列類,為我們快速搭建高質量的多線程程序帶來極大的便利。

阻塞隊列與普通隊列的區別在于,當隊列是空的時,從隊列中獲取元素的操作將會被阻塞,或者當隊列是滿時,往隊列里添加元素的操作會被阻塞。試圖從空的阻塞隊列中獲取元素的線程將會被阻塞,直到其他的線程往空的隊列插入新的元素。同樣,試圖往已滿的阻塞隊列中添加新元素的線程同樣也會被阻塞,直到其他的線程使隊列重新變得空閑起來,如從隊列中移除一個或者多個元素,或者完全清空隊列,下圖展示了如何通過阻塞隊列來合作:



線程1往阻塞隊列中添加元素,而線程2從阻塞隊列中移除元素

?

BlockingQueue接口方法

public interface BlockingQueue<E> extends Queue<E> {//將給定元素設置到隊列中,如果設置成功返回true, 否則返回false。如果是往限定了長度的隊列中設置值,推薦使用offer()方法。 如果隊列已滿,則拋出一個IIIegaISlabEepeplian異常,不可add nullboolean add(E e);//將給定的元素設置到隊列中,如果設置成功返回true, 否則返回false. e的值不能為空,否則拋出空指針異常。boolean offer(E e);//將元素設置到隊列中,如果隊列中沒有多余的空間,該方法會一直阻塞,直到隊列中有多余的空間。void put(E e) throws InterruptedException;//將給定元素在給定的時間內設置到隊列中,如果設置成功返回true, 否則返回false.boolean offer(E e, long timeout, TimeUnit unit)throws InterruptedException;//從隊列中獲取值,如果隊列中沒有值,線程會一直阻塞,直到隊列中有值,并且該方法取得了該值。E take() throws InterruptedException;//在給定的時間里,從隊列中獲取值,時間到了直接調用普通的poll方法,為null則直接返回null。E poll(long timeout, TimeUnit unit)throws InterruptedException;//獲取隊列中剩余的空間。int remainingCapacity();//從隊列中移除指定的值。boolean remove(Object o);//判斷隊列中是否擁有該值。public boolean contains(Object o);//將隊列中值,全部移除,并發設置到給定的集合中。int drainTo(Collection<? super E> c);//指定最多數量限制將隊列中值,全部移除,并發設置到給定的集合中。int drainTo(Collection<? super E> c, int maxElements); }

?

阻塞隊列實現

?

隊列有界性鎖數據結構
ArrayBlockingQueuebounded(有界)加鎖arrayList
LinkedBlockingQueueoptionally-bounded加鎖linkedList
PriorityBlockingQueueunbounded加鎖heap
DelayQueueunbounded加鎖heap
SynchronousQueuebounded加鎖
LinkedTransferQueueunbounded加鎖heap
LinkedBlockingDequeunbounded無鎖heap

下面分別簡單介紹一下:

  • ArrayBlockingQueue:是一個用數組實現的有界阻塞隊列,此隊列按照先進先出(FIFO)的原則對元素進行排序。支持公平鎖和非公平鎖。【注:每一個線程在獲取鎖的時候可能都會排隊等待,如果在等待時間上,先獲取鎖的線程的請求一定先被滿足,那么這個鎖就是公平的。反之,這個鎖就是不公平的。公平的獲取鎖,也就是當前等待時間最長的線程先獲取鎖】。參考:ArrayBlockingQueue源碼

  • LinkedBlockingQueue:一個由鏈表結構組成的有界隊列,此隊列的長度為Integer.MAX_VALUE。此隊列按照先進先出的順序進行排序。參考:LinkedBlockingQueue源碼
  • PriorityBlockingQueue: 一個支持線程優先級排序的無界隊列,默認自然序進行排序,也可以自定義實現compareTo()方法來指定元素排序規則,不能保證同優先級元素的順序。參考:PriorityBlockingQueue源碼
  • DelayQueue: 一個實現PriorityBlockingQueue實現延遲獲取的無界隊列,在創建元素時,可以指定多久才能從隊列中獲取當前元素。只有延時期滿后才能從隊列中獲取元素。(DelayQueue可以運用在以下應用場景:1.緩存系統的設計:可以用DelayQueue保存緩存元素的有效期,使用一個線程循環查詢DelayQueue,一旦能從DelayQueue中獲取元素時,表示緩存有效期到了。2.定時任務調度。使用DelayQueue保存當天將會執行的任務和執行時間,一旦從DelayQueue中獲取到任務就開始執行,從比如TimerQueue就是使用DelayQueue實現的。)。參考:DelayQueue源碼
  • SynchronousQueue: 一個不存儲元素的阻塞隊列,每一個put操作必須等待take操作,否則不能添加元素。支持公平鎖和非公平鎖。SynchronousQueue的一個使用場景是在線程池里。Executors.newCachedThreadPool()就使用了SynchronousQueue,這個線程池根據需要(新任務到來時)創建新的線程,如果有空閑線程則會重復使用,線程空閑了60秒后會被回收。參考:SynchronousQueue解析
  • LinkedTransferQueue: 一個由鏈表結構組成的無界阻塞隊列,相當于其它隊列,LinkedTransferQueue隊列多了transfer和tryTransfer方法。
  • LinkedBlockingDeque: 一個由鏈表結構組成的雙向阻塞隊列。隊列頭部和尾部都可以添加和移除元素,多線程并發時,可以將鎖的競爭最多降到一半。參考:LinkedBlockingDeque源碼

方法實現

繼承自AbstractQueue的方法

public boolean add(E e) {if (offer(e))return true;elsethrow new IllegalStateException("Queue full");}public E remove() {E x = poll();if (x != null)return x;elsethrow new NoSuchElementException();}public E element() {E x = peek();if (x != null)return x;elsethrow new NoSuchElementException();}public void clear() {while (poll() != null);}public boolean addAll(Collection<? extends E> c) {if (c == null)throw new NullPointerException();if (c == this)throw new IllegalArgumentException();boolean modified = false;for (E e : c)if (add(e))modified = true;return modified;}

示例

DelayQueue

java中DelayQueue的一個使用陷阱分析

?

總結

以上是生活随笔為你收集整理的Java并发包--阻塞队列(BlockingQueue)的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。