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

歡迎訪問(wèn) 生活随笔!

生活随笔

當(dāng)前位置: 首頁(yè) > 编程资源 > 编程问答 >内容正文

编程问答

delay在java中有什么用_java中DelayQueue的使用

發(fā)布時(shí)間:2025/3/15 编程问答 30 豆豆
生活随笔 收集整理的這篇文章主要介紹了 delay在java中有什么用_java中DelayQueue的使用 小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

java中DelayQueue的使用

簡(jiǎn)介

今天給大家介紹一下DelayQueue,DelayQueue是BlockingQueue的一種,所以它是線程安全的,DelayQueue的特點(diǎn)就是插入Queue中的數(shù)據(jù)可以按照自定義的delay時(shí)間進(jìn)行排序。只有delay時(shí)間小于0的元素才能夠被取出。

DelayQueue

先看一下DelayQueue的定義:

public class DelayQueue extends AbstractQueue

implements BlockingQueue

從定義可以看到,DelayQueue中存入的對(duì)象都必須是Delayed的子類。

Delayed繼承自Comparable,并且需要實(shí)現(xiàn)一個(gè)getDelay的方法。

為什么這樣設(shè)計(jì)呢?

因?yàn)镈elayQueue的底層存儲(chǔ)是一個(gè)PriorityQueue,在之前的文章中我們講過(guò)了,PriorityQueue是一個(gè)可排序的Queue,其中的元素必須實(shí)現(xiàn)Comparable方法。而getDelay方法則用來(lái)判斷排序后的元素是否可以從Queue中取出。

DelayQueue的應(yīng)用

DelayQueue一般用于生產(chǎn)者消費(fèi)者模式,我們下面舉一個(gè)具體的例子。

首先要使用DelayQueue,必須自定義一個(gè)Delayed對(duì)象:

@Data

public class DelayedUser implements Delayed {

private String name;

private long avaibleTime;

public DelayedUser(String name,long delayTime){

this.name=name;

//avaibleTime = 當(dāng)前時(shí)間+ delayTime

this.avaibleTime=delayTime + System.currentTimeMillis();

}

@Override

public long getDelay(TimeUnit unit) {

//判斷avaibleTime是否大于當(dāng)前系統(tǒng)時(shí)間,并將結(jié)果轉(zhuǎn)換成MILLISECONDS

long diffTime= avaibleTime- System.currentTimeMillis();

return unit.convert(diffTime,TimeUnit.MILLISECONDS);

}

@Override

public int compareTo(Delayed o) {

//compareTo用在DelayedUser的排序

return (int)(this.avaibleTime - ((DelayedUser) o).getAvaibleTime());

}

}

上面的對(duì)象中,我們需要實(shí)現(xiàn)getDelay和compareTo方法。

接下來(lái)我們創(chuàng)建一個(gè)生產(chǎn)者:

@Slf4j

@Data

@AllArgsConstructor

class DelayedQueueProducer implements Runnable {

private DelayQueue delayQueue;

private Integer messageCount;

private long delayedTime;

@Override

public void run() {

for (int i = 0; i < messageCount; i++) {

try {

DelayedUser delayedUser = new DelayedUser(

new Random().nextInt(1000)+"",delayedTime);

log.info("put delayedUser {}",delayedUser);

delayQueue.put(delayedUser);

Thread.sleep(500);

} catch (InterruptedException e) {

log.error(e.getMessage(),e);

}

}

}

}

在生產(chǎn)者中,我們每隔0.5秒創(chuàng)建一個(gè)新的DelayedUser對(duì)象,并入Queue。

再創(chuàng)建一個(gè)消費(fèi)者:

@Slf4j

@Data

@AllArgsConstructor

public class DelayedQueueConsumer implements Runnable {

private DelayQueue delayQueue;

private int messageCount;

@Override

public void run() {

for (int i = 0; i < messageCount; i++) {

try {

DelayedUser element = delayQueue.take();

log.info("take {}",element );

} catch (InterruptedException e) {

log.error(e.getMessage(),e);

}

}

}

}

在消費(fèi)者中,我們循環(huán)從queue中獲取對(duì)象。

最后看一個(gè)調(diào)用的例子:

@Test

public void useDelayedQueue() throws InterruptedException {

ExecutorService executor = Executors.newFixedThreadPool(2);

DelayQueue queue = new DelayQueue<>();

int messageCount = 2;

long delayTime = 500;

DelayedQueueConsumer consumer = new DelayedQueueConsumer(

queue,messageCount);

DelayedQueueProducer producer = new DelayedQueueProducer(

queue,messageCount,delayTime);

// when

executor.submit(producer);

executor.submit(consumer);

// then

executor.awaitTermination(5,TimeUnit.SECONDS);

executor.shutdown();

}

上面的測(cè)試?yán)又?#xff0c;我們定義了兩個(gè)線程的線程池,生產(chǎn)者產(chǎn)生兩條消息,delayTime設(shè)置為0.5秒,也就是說(shuō)0.5秒之后,插入的對(duì)象能夠被獲取到。

線程池在5秒之后會(huì)被關(guān)閉。

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

[pool-1-thread-1] INFO com.flydean.DelayedQueueProducer - put delayedUser DelayedUser(name=917,avaibleTime=1587623188389)

[pool-1-thread-2] INFO com.flydean.DelayedQueueConsumer - take DelayedUser(name=917,avaibleTime=1587623188389)

[pool-1-thread-1] INFO com.flydean.DelayedQueueProducer - put delayedUser DelayedUser(name=487,avaibleTime=1587623188899)

[pool-1-thread-2] INFO com.flydean.DelayedQueueConsumer - take DelayedUser(name=487,avaibleTime=1587623188899)

我們看到消息的put和take是交替進(jìn)行的,符合我們的預(yù)期。

如果我們做下修改,將delayTime修改為50000,那么在線程池關(guān)閉之前插入的元素是不會(huì)過(guò)期的,也就是說(shuō)消費(fèi)者是無(wú)法獲取到結(jié)果的。

總結(jié)

DelayQueue是一種有奇怪特性的BlockingQueue,可以在需要的時(shí)候使用。

歡迎關(guān)注我的公眾號(hào):程序那些事,更多精彩等著您!

更多內(nèi)容請(qǐng)?jiān)L問(wèn) www.flydean.com

相關(guān)文章

總結(jié)

如果覺(jué)得編程之家網(wǎng)站內(nèi)容還不錯(cuò),歡迎將編程之家網(wǎng)站推薦給程序員好友。

本圖文內(nèi)容來(lái)源于網(wǎng)友網(wǎng)絡(luò)收集整理提供,作為學(xué)習(xí)參考使用,版權(quán)屬于原作者。

如您喜歡交流學(xué)習(xí)經(jīng)驗(yàn),點(diǎn)擊鏈接加入交流1群:1065694478(已滿)交流2群:163560250

總結(jié)

以上是生活随笔為你收集整理的delay在java中有什么用_java中DelayQueue的使用的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。

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