<kbd id="afajh"><form id="afajh"></form></kbd>
<strong id="afajh"><dl id="afajh"></dl></strong>
    <del id="afajh"><form id="afajh"></form></del>
        1. <th id="afajh"><progress id="afajh"></progress></th>
          <b id="afajh"><abbr id="afajh"></abbr></b>
          <th id="afajh"><progress id="afajh"></progress></th>

          Java中常用的七個(gè)阻塞隊(duì)列第二篇DelayQueue源碼介紹

          共 1918字,需瀏覽 4分鐘

           ·

          2021-06-16 10:17

          Java中常用的七個(gè)阻塞隊(duì)列第二篇DelayQueue源碼介紹

          通過前面兩篇文章,我們對(duì)隊(duì)列有了了解及已經(jīng)認(rèn)識(shí)了常用阻塞隊(duì)列中的三個(gè)了。本篇我們繼續(xù)介紹剩下的幾個(gè)隊(duì)列。

          本文主要內(nèi)容:通過源碼學(xué)習(xí)Delayqueue及理解Dqueue并用代碼簡(jiǎn)單演示使用場(chǎng)景。

          本文出自凱哥Java(kaigejava)的《凱哥Java并發(fā)系列》之《Java并發(fā)編程之隊(duì)列》系列的第三篇:《Java中常用的七個(gè)阻塞隊(duì)列第二篇DelayQueue源碼介紹》

          Java中常用的幾個(gè)隊(duì)列中,阻塞隊(duì)列還有四個(gè)沒介紹。如下圖:


          DelayQueue

          先上總結(jié)腦圖:

          編輯

          來看看構(gòu)造器:


          支持無參和支持直接存放一個(gè)集合的。

          再來看看為什么說DQueue隊(duì)列使用的是PriorityQueue實(shí)現(xiàn)的呢?

          來看看源碼:

          在添加元素的offer方法源碼中,我們可以看到最終調(diào)用的是q.offer(e)這個(gè)方法的。那么q又是什么呢?我們接著跟下去:private final PriorityQueue<E> q = new PriorityQueue<E>();。發(fā)現(xiàn)q是PriorityQueue這個(gè)隊(duì)列。如下圖:


          為什么說可以延時(shí)呢?

          我們來看看DQueyue類的定義:

          public class DelayQueue<E extends Delayed> extends AbstractQueue<E>

          implements BlockingQueue<E> {}

          從源碼中,我們可以看到DQueue隊(duì)列中存放的元素必須要實(shí)現(xiàn)Delayed接口。

          我們?cè)趤砜纯碊elayed接口的方法:


          只有,long getDelay(TimeUnit unit);方法。設(shè)置等待時(shí)間。

          在從隊(duì)列中獲取數(shù)據(jù)的時(shí)候會(huì)對(duì)超時(shí)時(shí)間進(jìn)行判斷的。當(dāng)超時(shí)時(shí)間小于等于0的時(shí)候,才會(huì)調(diào)用priorityQueue隊(duì)列的poll()方法。具體源碼如下:


          從源碼中,我們可以看到,DQueue延時(shí)處理的:


          無界怎么理解?

          說DQueue無界,我們應(yīng)該從源碼中查找。DQueue隊(duì)列是基于PriorityQueue隊(duì)列來實(shí)現(xiàn)的。那么我們就來看看PriorityQueue隊(duì)列添加元素的源碼。


          從上圖中,我們可以看到,在添加元素的時(shí)候offer方法會(huì)進(jìn)行判斷,當(dāng)i的值大于等于隊(duì)列的長(zhǎng)的時(shí)候,會(huì)調(diào)用grow()方法來進(jìn)行擴(kuò)容。在grow方法中,我們可以看到會(huì)使用Arrsys.copyof()方法復(fù)制一份給隊(duì)列。這樣隊(duì)列就完成了庫(kù)容。沒有大小的限制。所以說是無界的。

          阻塞理解

          當(dāng)隊(duì)列為空的時(shí)候,“獲取/取”元素操作將會(huì)block,被阻塞著。我們來看看源碼是怎么實(shí)現(xiàn)的。


          從源碼中我們可以看到,當(dāng)從隊(duì)列中獲取元素的時(shí)候,先判斷,如果第一個(gè)元素為空的時(shí)候,就等待。當(dāng)?shù)却臅r(shí)間小于等于延時(shí)時(shí)間的話,就從隊(duì)列中poll了;如果leader不為空的話,說明當(dāng)前隊(duì)列不是隊(duì)首元素,依然await。

          支持優(yōu)先級(jí)

          因?yàn)樵赑Queue隊(duì)列的添加方法中,使用了comparator.compare方法。源碼如下圖:


          所以通過源碼分析我們可以到得到DelayQueue如下腦圖:


          使用場(chǎng)景:

          DQueue非常有用的。我們利用DQueue的延時(shí)特性,可以講DQueue應(yīng)用于以下場(chǎng)景:

          1:緩存的設(shè)計(jì)??梢岳肈queue保存緩存元素的有效期。使用一個(gè)線程循環(huán)的從隊(duì)列中獲取數(shù)據(jù)。一旦獲取到數(shù)據(jù),就說明緩存有效期到了。

          2:定時(shí)任務(wù)調(diào)度??梢允褂肈queue保存需要執(zhí)行的任務(wù)和任務(wù)執(zhí)行的時(shí)間,一旦從DQueue中獲取到了任務(wù),就開始執(zhí)行任務(wù)了。比如TimerQueue就是使用了DelayQueue來實(shí)現(xiàn)的。

          下面凱哥(凱哥Java:kaigejava)通過代碼簡(jiǎn)單演示模擬緩存過期時(shí)間的案例。

          代碼演示:

          需求:模擬緩存設(shè)置有效期。

          說明:當(dāng)從隊(duì)列中獲取到元素,說明元素的有效期到了。

          模擬緩存的對(duì)象:


          構(gòu)造器:


          需要注意:time=傳遞的time+當(dāng)前時(shí)間。

          實(shí)現(xiàn)了Delayed接口,需要重寫getDelay和compartTo方法。

          重寫方法如下:


          返回的是time與當(dāng)前時(shí)間之間的差值。

          compareTo方法如下:


          調(diào)用方法:


          來看看運(yùn)行結(jié)果:


          從運(yùn)行結(jié)果中,我們可以看到,從打印出開始獲取到k1的輸出之間相差1s;K1與k2之間相差2s;K3和K2之間也相差2s.符合我們上面預(yù)設(shè)的時(shí)間差。



          瀏覽 69
          點(diǎn)贊
          評(píng)論
          收藏
          分享

          手機(jī)掃一掃分享

          分享
          舉報(bào)
          評(píng)論
          圖片
          表情
          推薦
          點(diǎn)贊
          評(píng)論
          收藏
          分享

          手機(jī)掃一掃分享

          分享
          舉報(bào)
          <kbd id="afajh"><form id="afajh"></form></kbd>
          <strong id="afajh"><dl id="afajh"></dl></strong>
            <del id="afajh"><form id="afajh"></form></del>
                1. <th id="afajh"><progress id="afajh"></progress></th>
                  <b id="afajh"><abbr id="afajh"></abbr></b>
                  <th id="afajh"><progress id="afajh"></progress></th>
                  在线成人中文字幕无码影 | 97色色色色 | 猫咪AV成人永久网站在线观看 | 91无码秘 在线无码观看蜜桃 | 免费无码久久久久成人 |