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

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 编程语言 > java >内容正文

java

《Java并发编程的艺术》之阻塞队列

發(fā)布時(shí)間:2023/12/10 java 58 豆豆
生活随笔 收集整理的這篇文章主要介紹了 《Java并发编程的艺术》之阻塞队列 小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

阻塞隊(duì)列是一個(gè)支持兩個(gè)附加操作的隊(duì)列。這兩個(gè)附加的操作支持阻塞的插入和移除方法:

1) 支持阻塞的插入方法:當(dāng)隊(duì)列滿時(shí),隊(duì)列會(huì)阻塞執(zhí)行插入的線程
2) 支持阻塞的移除方法:當(dāng)隊(duì)列空時(shí),隊(duì)列會(huì)阻塞執(zhí)行移除的線程

方法總結(jié):

方法/處理方式拋出異常返回特殊值一直阻塞超時(shí)退出
插入方法add(e)offer(e)put(e)offer(e, time, unit)
移除方法poll()take()poll(time, unit)
檢測(cè)方法element()peek()
  • 拋出異常:當(dāng)隊(duì)列滿時(shí),插入元素會(huì)拋出IllegalStateException;
  • 返回特殊值:offer()是入隊(duì)方法,當(dāng)插入成功時(shí)返回true,插入失敗返回false;poll()是出隊(duì)方法,當(dāng)出隊(duì)成功時(shí)返回元素的值,隊(duì)列為空時(shí)返回null
  • 一直阻塞:當(dāng)隊(duì)列滿時(shí),阻塞執(zhí)行插入方法的線程;當(dāng)隊(duì)列空時(shí),阻塞執(zhí)行出隊(duì)方法的線程
  • 超時(shí)退出:顧名思義

在JDK7里,Java的阻塞隊(duì)列總共有七個(gè),每個(gè)類都繼承AbstractQueue:

  • ArrayBlockingQueue
  • LinkedTransferQueue
  • SynchronousQueue
  • DelayQueue
  • LinkedBlockingDeque
  • LinkedBlockingQueue
  • PriorityBlockingQueue

ArrayBlockingQueue

該類是通過數(shù)組實(shí)現(xiàn)的有界阻塞隊(duì)列,此隊(duì)列按照FIFO的原則對(duì)元素進(jìn)行排列。默認(rèn)情況下不保證線程公平的訪問隊(duì)列,所謂公平訪問是指阻塞的線程,可以按照阻塞的先后順序訪問隊(duì)列,即先阻塞的先訪問。公平訪問是由ReentrantLock的公平鎖實(shí)現(xiàn)的:

public ArrayBlockingQueue(int capacity, boolean fair) {if (capacity <= 0)throw new IllegalArgumentException();this.items = new Object[capacity];lock = new ReentrantLock(fair);notEmpty = lock.newCondition();notFull = lock.newCondition(); }
  • 因?yàn)橹苯觿?chuàng)建的數(shù)組,ArrayBlockingQueue的長(zhǎng)度無法更改,
  • 當(dāng)ReentrantLock設(shè)置為公平鎖后,后續(xù)所有Lock競(jìng)爭(zhēng)中都會(huì)是公平競(jìng)爭(zhēng),沒看過Condition原理的小伙伴會(huì)想,那和Condition有什么關(guān)系呢?答案是Condition在被喚醒時(shí)也要參與競(jìng)爭(zhēng)Lock,那么在Lock競(jìng)爭(zhēng)中都會(huì)遵守公平競(jìng)爭(zhēng)。
  • LinkedBlockingQueue

    該類是一個(gè)用鏈表實(shí)現(xiàn)的有界阻塞隊(duì)列(也不算有界,只是因?yàn)橛?jì)數(shù)器最多只能計(jì)Integer.MAX_VALUE)。此隊(duì)列的默認(rèn)和最大長(zhǎng)度為Integer.MAX_VALUE。按照先進(jìn)先出的原則對(duì)元素進(jìn)行排列。

    PriorityBlockingQueue

    該類是一個(gè)支持優(yōu)先級(jí)的無界阻塞隊(duì)列。默認(rèn)情況下元素采取自然升序的排序方式。也可以自定義類實(shí)現(xiàn)compareTo()來指定元素排序規(guī)則,或者初始化時(shí)指定Comparator來對(duì)元素排序。
    詳見:坑還沒填,遲點(diǎn)填

    DelayQueue

    支持延時(shí)獲取元素的無界阻塞隊(duì)列。隊(duì)列使用PriorityQueue來實(shí)現(xiàn),隊(duì)列中的元素必須實(shí)現(xiàn)Delayed接口,再創(chuàng)建元素時(shí)可以指定多久才能從隊(duì)列中獲取當(dāng)前原色,只有在延遲期滿時(shí)才能從隊(duì)列中提取元素。
    運(yùn)用場(chǎng)景:

    • 緩存系統(tǒng)的設(shè)計(jì):可以用DelayQueue保存緩存元素的有效期,使用一個(gè)線程循環(huán)查詢DelayQueue,一旦能從DelayQueue中獲取元素,表示緩存有效期到了
    • 定時(shí)任務(wù)調(diào)度:使用DelayQueue保存當(dāng)天將會(huì)執(zhí)行的任務(wù)和執(zhí)行時(shí)間,一旦從DelayQueue中獲取到任務(wù)就開始執(zhí)行,比如TimerQueue

    執(zhí)行流程如下所示:

    首先實(shí)現(xiàn)Delayed接口:
    java @Override public long getDelay(TimeUnit unit){ // 返回當(dāng)前元素還需要等待多久,當(dāng)返回<0的值時(shí),表示可以出隊(duì);>0時(shí),表示仍需要等待 }

    第二步,每次offer()時(shí),往PriorityQueue插入元素會(huì)自行排序,按照自然升序排序

    第三步,每次獲取時(shí)(調(diào)用take(),才能有阻塞的功能),如果時(shí)間未滿會(huì)先阻塞

    for (;;) {E first = q.peek();if (first == null)available.await();else {long delay = first.getDelay(NANOSECONDS);if (delay <= 0)return q.poll();first = null; // don't retain ref while waitingif (leader != null)available.await();else {Thread thisThread = Thread.currentThread();leader = thisThread;try {available.awaitNanos(delay);} finally {if (leader == thisThread)leader = null;}}} }

    具體的可以看: 了解之DelayQueue

    SynchronousQueue

    一個(gè)不存儲(chǔ)元素的隊(duì)列,生產(chǎn)者生產(chǎn)一個(gè),消費(fèi)者消費(fèi)一個(gè),每一個(gè)put操作都需要等待一個(gè)take操作。該隊(duì)列主要負(fù)責(zé)生產(chǎn)者線程處理的數(shù)據(jù)傳遞給消費(fèi)者線程。比較適合傳遞性場(chǎng)景。其吞吐量高于ArrayBlockingQueue和LinkedBlockingQueue

    LinkedTransferQueue

    該類主要添加了兩個(gè)方法:transfer()和tryTransfer()
    transfer() 主要是當(dāng)消費(fèi)者線程在等待的時(shí)候,生產(chǎn)者一產(chǎn)生元素,就立刻交給消費(fèi)者,不需要再進(jìn)行額外的入隊(duì)操作;如果沒有消費(fèi)者在等待,就先進(jìn)入隊(duì)尾。
    tryTransfer() 用來試探生產(chǎn)者傳入的元素是否能直接傳給消費(fèi)者。

    具體的可以看:了解之LinkedTansferQueue

    總結(jié)

    • ArrayBlockingQueue
    • LinkedBlockingQueue
    • LinkedBlockingDeque
    • SynchronousQueue
      上面四個(gè)是較為簡(jiǎn)單的,數(shù)據(jù)結(jié)構(gòu)和各個(gè)方法都較為簡(jiǎn)單就不一一闡述了。剩下三個(gè)則是比較大頭的,而且比較新穎,打算單獨(dú)拎出來講解

    該章主要是粗略的了解一下其他阻塞隊(duì)列的功能,對(duì)于一些不常見的類,后續(xù)會(huì)補(bǔ)上詳細(xì)的分析(其實(shí)是先補(bǔ)充一波數(shù)據(jù)結(jié)構(gòu)和算法)

    轉(zhuǎn)載于:https://www.cnblogs.com/codeleven/p/10963265.html

    總結(jié)

    以上是生活随笔為你收集整理的《Java并发编程的艺术》之阻塞队列的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。