延遲佇列 DelayQueue 使用與原始碼解析

2021-10-10 22:23:51 字數 1874 閱讀 7138

當記憶體中有一堆的客戶資訊,需要實時移除vip到期的客戶的特權時有以下做法。

以上做法2有現成的佇列可以使用,就是接下來要說的延遲佇列。

是不是跟優先佇列很像。delayqueue其內部就聚合了乙個優先佇列。

其實現了queue,collection,blockingqueue。這裡注意一點,因為delayqueue其泛型被指定為需要繼承delayed介面。所以放入的元素也是要繼承該介面的。先來看看delayed介面

public

inte***ce

delayed

extends

comparable

其還繼承了comparable介面

public

inte***ce

comparable

存放的物件需實現上述兩個介面,那麼就要重寫這兩個方法。乙個用於獲取當前剩餘的延遲時間,乙個用於物件之間比較大小。

檢索並刪除此佇列的頭部。如有元素沒到過期時間需要等待直到該元素過期。

先判斷佇列有元素,如果沒有執行緒等待,如果有元素,獲取佇列元素的過期時間,如果到期就會執行出隊操作。否則需要判斷一下leader執行緒是否為null,如果leader 不為空 說明已經有執行緒在等待堆頂元素過期,加入到等待佇列中等待喚醒即當前執行緒變成了follower,如果leader為空那麼說明並沒有執行緒在等待頭節點過期,那麼將當前執行緒設定為leder執行緒,並且等待頭節點的超時時間後喚醒執行緒。

public e take()

throws interruptedexception

finally}}

}}finally

}

將指定的元素插入此延遲佇列。由於佇列是無界的,因此此方法將永遠不會阻塞。但是指定的存放的元素需要實現 delayed介面。

將元素入隊到優先佇列中(底層儲存結構為優先順序佇列),入隊後需要檢查一下剛剛插入的元素是否是優先順序最高的(延遲最近乙個到期的)如果剛剛存入元素就是延遲最近乙個到期的需要先把leader執行緒置為null,再喚醒乙個take執行緒。那麼執行緒就會在上述take方法中的第一第二第三個await時被喚醒,進入下次迴圈再執行take流程。

public

void

put(e e)

public

boolean

offer

(e e)

return

true;}

finally

}

底層儲存使用了優先順序佇列

存放的元素需要實現getdelay()方法和compareto()方法,用來確定元素是否到期,以及比較元素之間的優先順序

堆頂元素只有乙個,使用了leader/follower執行緒模型。獲取元素時如果元素還未到過期時間,需要檢查leader執行緒是否為空,為空的話說明還沒有執行緒監聽堆頂元素。需要將自己休眠指定時間後喚醒處理堆頂元素

入隊時需要檢查一下剛剛插入的元素是否是優先順序最高的(延遲最近乙個到期的)是的話需要手動喚醒乙個take執行緒, 並且把leader執行緒置為null。被喚醒的執行緒需要去檢查堆頂元素是否過期。

深度解析延遲佇列DelayQueue

有時候,我們有一些任務需要 稍後 來做,比如一些連線需要空閒一段時間後再關閉,session需要空閒一段時間後自動退出。這個時候就需要一些可以延遲執行任務的工具。delayqueue 延遲佇列 就是乙個可以實現類似功能的工具。由於本篇會涉及到優先佇列priorityqueue,所以預先閱讀 深度解析...

DelayQueue實現延遲訊息

最近想做乙個定時推送訊息的功能,經過調研了解到delayqueue,訊息物件需實現delayed介面裡的getdelay timeunit unit 方法,由於delayed繼承了comparable故需要實現compareto方法,可用於決定訊息的推送次序。以考試為例,設定每個考生的交卷時間點。學...

阻塞佇列之DelayQueue

特點 1 內部佇列基於priorityqueue,其要求放入的元素不能為null 2 放置在內的物件,只有滿足條件 到期 且 排在佇列出口的 才能取出 3 放置在內的物件必須實現delayed介面,該介面有個getdelay方法,用於判斷是否到達執行時間 示例 delayqueue 可以延時取出的佇...