最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

Java?延時隊列及簡單使用方式詳解

 更新時間:2023年08月10日 11:42:24   作者:假女吖?  
這篇文章主要介紹了Java延時隊列簡單使用方式,通過本文學習知道延時隊列是什么可以用來干什么,本文通過實例代碼介紹的非常詳細,需要的朋友可以參考下

Java 延時隊列,簡單使用方式

前言:首先我們要知道延時隊列是什么?可以用來干什么?

是什么?

看名稱 隊列 可想而知 先進先出 的一個集合。但我們的延時隊列并沒有完全的遵循這個理念。

DelayQueue 內(nèi)部其實是基于我們的 優(yōu)先隊列 來實現(xiàn)的,也就是元素的先后順序是按元素的 Comparable 接口提供的順序來 出隊 的。

DelayQueue 內(nèi)部的元素必須是 Delayed 的的實現(xiàn)類 而 Delayed 的父接口是 Comparable<Delayed> 。

Delayed 接口中需要我們實現(xiàn)一個 long getDelay(TimeUnit unit); 元素的剩余時間 TTL 。

干什么?

  • 定時任務。
  • 重試(5秒重試)。
  • 延時通知。

都可以基于延時隊列來實現(xiàn)。

開發(fā)中遇到一個這樣的需求。

需要一個集合來維護熱點數(shù)據(jù),但這個熱點數(shù)據(jù)是有時效性的,我們在去查詢的時候先要判斷下這個熱點數(shù)據(jù)不存在,或者不在有效期內(nèi)的。才能走剩下的邏輯。

當然這個需求聽起來并不復雜。

我們自己實現(xiàn)的話。

是不是需要一個有順序的集合?

是不是還每個元素都有一個有效期?

是不是還得保證元素出隊的順序?

如果說還有另外一個地方需要復用,我們是不是還得再寫一套這樣的邏輯。

所以,我們可以直接使用 DelayQueue 來實現(xiàn)這個需求,他天生就能保證我們的集合是有順序的,并且保證過期的元素不在集合內(nèi)。

簡單使用

延時對象

@Data
static class SimpleDelayed<T> implements Delayed {
    /**
     * 對象創(chuàng)建時間
     */
    @JsonIgnore
    private final Date createDate;
    /**
     * 延時數(shù)(單位毫秒)
     */
    private long delayCount;
    private T data;
    public SimpleDelayed(T data, long delayCount) {
        this.data = data;
        this.delayCount = delayCount;
        this.createDate = new Date();
    }
    @Override
    public long getDelay(TimeUnit unit) {
        long diff = this.createDate.getTime() + this.delayCount - System.currentTimeMillis();
        return unit.convert(diff, TimeUnit.MILLISECONDS);
    }
    @Override
    public int compareTo(Delayed delayed) {
        return Long.compare(this.getDelay(TimeUnit.MILLISECONDS),delayed.getDelay(TimeUnit.MILLISECONDS));
    }
}

注意: compareTo 提供的順序必須要與 getDelay 否則會出現(xiàn)元素過期了但是在隊列中。因為 DelayQueue 內(nèi)部維護的是一個 優(yōu)先隊列 。所以必須保證這兩順序是一致的。所以這里的 compareTo 直接比較了這兩的 剩余過期數(shù) 越小的越先出隊。反之會出現(xiàn), 延時時間 已過,但是沒有出隊。 compareTo 靠前,但是過期數(shù)未過的數(shù)卡著。

延時隊列工具類

@Slf4j
public class SimpleDelayQueueUtils {
   /**
     * 1.定義了一個延時隊列 隊列中元素是我們的SimpleDelayed
     */
    private final static DelayQueue<SimpleDelayed> SIMPLE_DELAYED_DELAY_QUEUE = new DelayQueue<>();
    static{
      	// 2.聲明一個異步線程
        CompletableFuture.runAsync(() -> {
          	// 3.通過自旋去出隊已過期的元素
            for (;;) {
                try {
					// 4.take() 對頭元素出隊。
                    log.info("元素已過期{}",SIMPLE_DELAYED_DELAY_QUEUE.take().getData());
                } catch (InterruptedException e) {
                    throw new RuntimeException(e);
                }
            }
        // 單個線程的線程池,為了不占用fork-join線程池
        }, Executors.newSingleThreadExecutor());
    }
    public static void add(SimpleDelayed... delayeds) {
        SIMPLE_DELAYED_DELAY_QUEUE.addAll(Arrays.asList(delayeds));
    }
  	// 測試
    public static void main(String[] args) {
        SimpleDelayed<String> nonceDelayed = new SimpleDelayQueueUtils.SimpleDelayed<>("111",5001);
        SimpleDelayed<String> nonceDelayed1 = new SimpleDelayQueueUtils.SimpleDelayed<>("222", 4500);
        SimpleDelayQueueUtils.add(nonceDelayed,nonceDelayed1);
    }
}

輸出

23:35:00.693 [pool-1-thread-1] INFO com.mfyuan.chenapioperation.util.SimpleDelayQueueUtils - 元素已過期222
23:35:01.189 [pool-1-thread-1] INFO com.mfyuan.chenapioperation.util.SimpleDelayQueueUtils - 元素已過期111

思考

這里的 data 元素是可以靈活替換的,因為我這里的需求是涉及到隊列中的元素是否過期。所以這些就已經(jīng)足夠了。

但是當我們把 data ,替換成 Runable 再把出隊的的元素通過線程池的方式去調用則就實現(xiàn)了 定時任務 。 重試 也可以當做 定時任務 來理解,就把當單做一個任務,如果任務執(zhí)行失敗了或者出現(xiàn)異常了,那么我們重新講元素放入延時隊列中即可。

后話

Redis來實現(xiàn)我這個功能,雖然可以實現(xiàn)但是有些地方實現(xiàn)的邏輯也是不簡單。更別說引入 redis 的開發(fā)成本,殺??不需要??刀。

Redis zset 是可以保證集合的元素有順序的, zset ttl 是指這個 zset 整體的過期時間。(不確定,)

到此這篇關于Java 延時隊列,簡單使用方式的文章就介紹到這了,更多相關java延時隊列內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關文章希望大家以后多多支持腳本之家!

相關文章

  • java注解的類型知識點總結

    java注解的類型知識點總結

    在本篇文章里小編給大家整理了一篇關于java注解的類型知識點總結內(nèi)容,有興趣的朋友們可以學習下。
    2021-03-03
  • IntelliJ?IDEA?2022.2?正式發(fā)布新功能體驗

    IntelliJ?IDEA?2022.2?正式發(fā)布新功能體驗

    IntelliJ?IDEA?2022.2為遠程開發(fā)功能帶來了多項質量改進,使其更美觀、更穩(wěn)定,新版本還具有多項值得注意的升級和改進,下面跟隨小編一起看看IDEA?2022.2新版本吧
    2022-08-08
  • Java中ArrayList類的源碼解析

    Java中ArrayList類的源碼解析

    本文主要介紹了Java中ArrayList類的源碼解析,具有很好的參考價值。下面跟著小編一起來看下吧
    2017-03-03
  • 解決IDEA中不能正常輸入光標變粗的問題

    解決IDEA中不能正常輸入光標變粗的問題

    這篇文章主要介紹了在IDEA中不能正常輸入光標變粗的解決方法,本文給大家介紹的非常詳細,對大家的學習或工作具有一定的參考借鑒價值,需要的朋友參考下吧
    2020-09-09
  • 解決springboot項目找不到resources目錄下的資源問題

    解決springboot項目找不到resources目錄下的資源問題

    這篇文章主要介紹了解決springboot項目找不到resources目錄下的資源問題,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2021-08-08
  • Java多線程使用阻塞隊列實現(xiàn)生產(chǎn)者消費者模型詳解

    Java多線程使用阻塞隊列實現(xiàn)生產(chǎn)者消費者模型詳解

    這篇文章主要介紹了Java多線程使用阻塞隊列實現(xiàn)生產(chǎn)者消費者模型詳解,主要講解阻塞隊列的特性、實際開發(fā)中常用的到的生產(chǎn)者消費者模型,以及生產(chǎn)者消費者模型解耦合、削峰填谷的好處,需要的朋友可以參考下
    2023-07-07
  • Java中CopyOnWriteArrayList的使用解析

    Java中CopyOnWriteArrayList的使用解析

    這篇文章主要介紹了Java中CopyOnWriteArrayList的使用解析,CopyOnWriteArrayList適合使用在讀操作遠遠大于寫操作的場景里,比如緩存,它不存在擴容的概念,每次寫操作都要復制一個副本,在副本的基礎上修改后改變Array引用,需要的朋友可以參考下
    2023-12-12
  • 解決mybatis使用foreach批量insert異常的問題

    解決mybatis使用foreach批量insert異常的問題

    這篇文章主要介紹了解決mybatis使用foreach批量insert異常的問題,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧
    2021-01-01
  • Java并發(fā)編程之Semaphore詳解

    Java并發(fā)編程之Semaphore詳解

    這篇文章主要介紹了Java并發(fā)編程之Semaphore詳解,Semaphore信號量可以用來控制同時訪問特定資源的線程數(shù)量,常用于限流場景,Semaphore接收一個int整型值,表示 許可證數(shù)量,需要的朋友可以參考下
    2023-11-11
  • Java 調用 HTTP 接口的 7 種方式示例代碼(全網(wǎng)最全指南)

    Java 調用 HTTP 接口的 7 種方式示例代碼(全網(wǎng)最全指南)

    在開發(fā)過程中,調用 HTTP 接口是最常見的需求之一,本文將詳細介紹 Java 中 7 種主流的調用 HTTP 接口的方式,包括每種工具的優(yōu)缺點和完整代碼實現(xiàn),感興趣的朋友一起看看吧
    2025-02-02

最新評論

无锡市| 闸北区| 即墨市| 昌平区| 乐至县| 平定县| 中宁县| 阿拉善盟| 潮安县| 集安市| 松溪县| 韶关市| 浦县| 双江| 通江县| 南溪县| 河南省| 平陆县| 邵阳市| 衡南县| 那曲县| 德清县| 永仁县| 万宁市| 太湖县| 化州市| 平顶山市| 贵溪市| 兴宁市| 和静县| 靖西县| 新绛县| 石狮市| 宁远县| 丹凤县| 平顶山市| 乡城县| 横山县| 莲花县| 崇仁县| 濉溪县|