欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

Java的延遲隊(duì)列之DelayQueue解讀

 更新時(shí)間:2023年12月13日 08:59:15   作者:得過(guò)且過(guò)的勇者y  
這篇文章主要介紹了Java的延遲隊(duì)列之DelayQueue解讀,DelayQueue的底層存儲(chǔ)是一個(gè)PriorityQueue,PriorityQueue是一個(gè)可排序的Queue,其中的元素必須實(shí)現(xiàn)Comparable接口的compareTo方法,需要的朋友可以參考下

一、DelayQueue的定義

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

DelayQueue是一個(gè)無(wú)界的BlockingQueue,是線程安全的(無(wú)界指的是隊(duì)列的元素?cái)?shù)量不存在上限,隊(duì)列的容量會(huì)隨著元素?cái)?shù)量的增加而擴(kuò)容,阻塞隊(duì)列指的是當(dāng)隊(duì)列內(nèi)元素?cái)?shù)量為0的時(shí)候,試圖從隊(duì)列內(nèi)獲取元素的線程將被阻塞或者拋出異常)

以上是阻塞隊(duì)列的特點(diǎn),而延遲隊(duì)列還擁有自己如下的特點(diǎn):

DelayQueue中存入的必須是實(shí)現(xiàn)了Delayed接口的對(duì)象(Delayed定義了一個(gè)getDelay的方法,用來(lái)判斷排序后的元素是否可以從Queue中取出,并且Delayed接口還繼承了Comparable用于排序),插入Queue中的數(shù)據(jù)根據(jù)compareTo方法進(jìn)行排序(DelayQueue的底層存儲(chǔ)是一個(gè)PriorityQueue,PriorityQueue是一個(gè)可排序的Queue,其中的元素必須實(shí)現(xiàn)Comparable接口的compareTo方法),并通過(guò)getDelay方法返回的時(shí)間確定元素是否可以出隊(duì),只有小于等于0的元素(即延遲到期的元素)才能夠被取出

延遲隊(duì)列不接收null元素

二、DelayQueue的作用

延遲隊(duì)列的作用顯然就是用于執(zhí)行延時(shí)任務(wù),如:

  1. 淘寶訂單業(yè)務(wù):下單之后如果三十分鐘之內(nèi)沒(méi)有付款就自動(dòng)取消訂單。
  2. 餓了嗎訂餐通知:下單成功后60s之后給用戶發(fā)送短信通知。
  3. 關(guān)閉空閑連接。服務(wù)器中,有很多客戶端的連接,空閑一段時(shí)間之后需要關(guān)閉之。
  4. 緩存。緩存中的對(duì)象,超過(guò)了空閑時(shí)間,需要從緩存中移出。
  5. 任務(wù)超時(shí)處理。在網(wǎng)絡(luò)協(xié)議滑動(dòng)窗口請(qǐng)求應(yīng)答式交互時(shí),處理超時(shí)未響應(yīng)的請(qǐng)求等。

三、DelayQueue的實(shí)現(xiàn)

定義延遲隊(duì)列元素

public class OrderDelayTask implements Delayed {
    
    private Long orderId;
    
    private long delayTime;

    public OrderDelayTask(Long orderId, long delayTime) {
        this.orderId = orderId;
        // 延遲時(shí)間加當(dāng)前時(shí)間
        this.delayTime = System.currentTimeMillis() + delayTime;
    }

    // 獲取任務(wù)剩余時(shí)間
    @Override
    public long getDelay(TimeUnit unit) {
        return unit.convert(delayTime - System.currentTimeMillis(), TimeUnit.MILLISECONDS);
    }

    @Override
    public int compareTo(Delayed o) {
        return Long.compare(delayTime, ((OrderDelayTask) o).delayTime);
    }
}

定義延遲隊(duì)列并交付容器管理

@Bean("orderDelayQueue")
public DelayQueue<OrderDelayTask> orderDelayQueue(){
    return new DelayQueue<OrderDelayTask>();
}

使用延遲隊(duì)列

@Autowired
private DelayQueue<OrderDelayObject> orderDelayQueue;

//發(fā)起訂單下單的時(shí)候?qū)⒂唵窝菔緦?duì)象放入orderDelayQueue
orderDelayQueue.add(
        new OrderDelayTask(
                "123456", // 訂單id
                30 * 60 * 1000, // 延遲時(shí)間:30分鐘
        )
);

開(kāi)啟線程處理延遲任務(wù)

@Component
public class DelayTaskRunner<OrderDelayTask> implements InitializingBean {
    
    @Autowired
    private DelayQueue<OrderDelayTask> orderDelayQueue;
    
    @Override
    public void afterPropertiesSet() throws Exception {
    	new Thread(() -> {
            try {
                while(true) {
                    OrderDelayTask task = orderDelayQueue.take();
                    // 當(dāng)隊(duì)列為null的時(shí)候,poll()方法會(huì)直接返回null, 不會(huì)拋出異常,但是take()方法會(huì)一直等待,因此會(huì)拋出一個(gè)InterruptedException類型的異常。(當(dāng)阻塞方法收到中斷請(qǐng)求的時(shí)候就會(huì)拋出InterruptedException異常)
                    Long orderId = task.getOrderId();
                    // 執(zhí)行業(yè)務(wù)
                }
            } catch (InterruptedException e) { 
                // 因?yàn)槭侵貙慠unnable接口的run方法,子類拋出的異常要小于等于父類的異常。而在Runnable中run方法是沒(méi)有拋異常的。所以此時(shí)是不能拋出InterruptedException異常。如果此時(shí)你只是記錄日志的話,那么就是一個(gè)不負(fù)責(zé)任的做法,因?yàn)樵诓东@InterruptedException異常的時(shí)候自動(dòng)的將是否請(qǐng)求中斷標(biāo)志置為了false。在捕獲了InterruptedException異常之后,如果你什么也不想做,那么就將標(biāo)志重新置為true,以便棧中更高層的代碼能知道中斷,并且對(duì)中斷作出響應(yīng)。
            	Thread.currentThread().interrupt();
            }
        }).start();
    }
}

四、DelayQueue實(shí)現(xiàn)延時(shí)任務(wù)的優(yōu)缺點(diǎn)

使用DelayQueue實(shí)現(xiàn)延時(shí)任務(wù)非常簡(jiǎn)單,而且簡(jiǎn)便,全部都是標(biāo)準(zhǔn)的JDK代碼實(shí)現(xiàn),不用引入第三方依賴(不依賴redis實(shí)現(xiàn)、消息隊(duì)列實(shí)現(xiàn)等),非常的輕量級(jí)。

它的缺點(diǎn)就是所有的操作都是基于應(yīng)用內(nèi)存的,一旦出現(xiàn)應(yīng)用單點(diǎn)故障,可能會(huì)造成延時(shí)任務(wù)數(shù)據(jù)的丟失。如果訂單并發(fā)量非常大,因?yàn)镈elayQueue是無(wú)界的,訂單量越大,隊(duì)列內(nèi)的對(duì)象就越多,可能造成OOM的風(fēng)險(xiǎn)。所以使用DelayQueue實(shí)現(xiàn)延時(shí)任務(wù),只適用于任務(wù)量較小的情況。

到此這篇關(guān)于Java的延遲隊(duì)列之DelayQueue解讀的文章就介紹到這了,更多相關(guān)延遲隊(duì)列DelayQueue內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • mybatis-plus分頁(yè)插件失效探究解決

    mybatis-plus分頁(yè)插件失效探究解決

    這篇文章主要為大家介紹了mybatis-plus分頁(yè)插件失效探究解決,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2023-07-07
  • Java使用正則表達(dá)式進(jìn)行匹配且對(duì)匹配結(jié)果逐個(gè)替換

    Java使用正則表達(dá)式進(jìn)行匹配且對(duì)匹配結(jié)果逐個(gè)替換

    這篇文章主要介紹了Java使用正則表達(dá)式進(jìn)行匹配且對(duì)匹配結(jié)果逐個(gè)替換,文章圍繞主題展開(kāi)詳細(xì)的內(nèi)容戒殺,具有一定的參考價(jià)值,需要的小伙伴可以參考一下
    2022-09-09
  • JVM內(nèi)存結(jié)構(gòu):程序計(jì)數(shù)器、虛擬機(jī)棧、本地方法棧

    JVM內(nèi)存結(jié)構(gòu):程序計(jì)數(shù)器、虛擬機(jī)棧、本地方法棧

    JVM 基本上是每家招聘公司都會(huì)問(wèn)到的問(wèn)題,它們會(huì)這么無(wú)聊問(wèn)這些不切實(shí)際的問(wèn)題嗎?很顯然不是。由 JVM 引發(fā)的故障問(wèn)題,無(wú)論在我們開(kāi)發(fā)過(guò)程中還是生產(chǎn)環(huán)境下都是非常常見(jiàn)的
    2021-06-06
  • Spring Security加密和匹配及原理解析

    Spring Security加密和匹配及原理解析

    我們開(kāi)發(fā)時(shí)進(jìn)行密碼加密,可用的加密手段有很多,比如對(duì)稱加密、非對(duì)稱加密、信息摘要等,本篇文章給大家介紹Spring Security加密和匹配及原理解析,感興趣的朋友一起看看吧
    2023-10-10
  • Spring IOC基于注解啟動(dòng)示例詳析

    Spring IOC基于注解啟動(dòng)示例詳析

    這篇文章主要給大家介紹了Spring IOC基于注解啟動(dòng)的相關(guān)資料,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2019-03-03
  • 零基礎(chǔ)寫Java知乎爬蟲之進(jìn)階篇

    零基礎(chǔ)寫Java知乎爬蟲之進(jìn)階篇

    前面幾篇文章,我們都是簡(jiǎn)單的實(shí)現(xiàn)了java爬蟲抓取內(nèi)容的問(wèn)題,那么如果遇到復(fù)雜情況,我們還能繼續(xù)那么做嗎?答案當(dāng)然是否定的,之前的僅僅是入門篇,都是些基礎(chǔ)知識(shí),給大家練手用的,本文我們就來(lái)點(diǎn)高大上的東西
    2014-11-11
  • Java實(shí)現(xiàn)的計(jì)算稀疏矩陣余弦相似度示例

    Java實(shí)現(xiàn)的計(jì)算稀疏矩陣余弦相似度示例

    這篇文章主要介紹了Java實(shí)現(xiàn)的計(jì)算稀疏矩陣余弦相似度功能,涉及java基于HashMap的數(shù)值計(jì)算相關(guān)操作技巧,需要的朋友可以參考下
    2018-07-07
  • java的繼承原理與實(shí)現(xiàn)方法詳解

    java的繼承原理與實(shí)現(xiàn)方法詳解

    這篇文章主要介紹了java的繼承原理與實(shí)現(xiàn)方法,結(jié)合實(shí)例形式詳細(xì)分析了Java繼承的概念、原理、用法及相關(guān)操作注意事項(xiàng),需要的朋友可以參考下
    2019-05-05
  • 淺談springMVC接收前端json數(shù)據(jù)的總結(jié)

    淺談springMVC接收前端json數(shù)據(jù)的總結(jié)

    下面小編就為大家分享一篇淺談springMVC接收前端json數(shù)據(jù)的總結(jié),具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧
    2018-03-03
  • Java如何使用JSR303校驗(yàn)數(shù)據(jù)與自定義校驗(yàn)注解

    Java如何使用JSR303校驗(yàn)數(shù)據(jù)與自定義校驗(yàn)注解

    這篇文章主要介紹了Java如何使用JSR303校驗(yàn)數(shù)據(jù)與自定義校驗(yàn)注解,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2020-09-09

最新評(píng)論