DelayQueue 使用示例

27 阅读2分钟

以下是一个简单的 Java 代码示例,演示了如何使用 DelayQueue 来实现你的需求。在这个示例中,我们创建了一个 DelayQueue 对象,并启动了三个线程将三个数据对象(data1data2data3)加入到延迟队列中,每个数据对象的延迟时间根据其索引计算。然后,我们启动了另外三个线程从延迟队列中执行 take 操作。

package com.example.demo;  

import java.util.concurrent.DelayQueue;  
import java.util.concurrent.Delayed;  
import java.util.concurrent.TimeUnit;  
  
public class DelayQueueExample {  
  
static class Data implements Delayed {  
String data;  
long delayTime; // 延迟时间点  
  
public Data(String data, long delayTime) {  
this.data = data;  
this.delayTime = System.currentTimeMillis() + delayTime;  
}  
  
@Override  
public long getDelay(TimeUnit unit) {  
return unit.convert(delayTime - System.currentTimeMillis(), TimeUnit.MILLISECONDS);  
}  
  
@Override  
public int compareTo(Delayed other) {  
if (this.delayTime < ((Data) other).delayTime) {  
return -1;  
} else if (this.delayTime > ((Data) other).delayTime) {  
return 1;  
}  
return 0;  
}  
  
@Override  
public String toString() {  
return "Data{" + "data='" + data + '\'' + ", delayTime=" + delayTime + '}';  
}  
}  
  
public static void main(String[] args) throws InterruptedException {  
DelayQueue<Data> delayQueue = new DelayQueue<>();  
  
// 启动线程将数据加入到延迟队列中  
for (int i = 0; i < 3; i++) {  
final int index = i;  
new Thread(() -> {  
try {  
Thread.sleep((index + 1) * 1000); // 模拟延迟时间  
delayQueue.put(new Data("data" + (index + 1), (index + 1) * 3000));  
System.out.println("Put " + delayQueue.peek() + " into delay queue.");  
} catch (InterruptedException e) {  
e.printStackTrace();  
}  
}).start();  
}  
  
// 启动线程从延迟队列中执行take操作  
for (int i = 0; i < 3; i++) {  
new Thread(() -> {  
try {  
Data data = delayQueue.take();  
System.out.println("Take " + data + " from delay queue.");  
} catch (InterruptedException e) {  
e.printStackTrace();  
}  
}).start();  
}  
}  
}

放入DelayQueue 中的元素都必须实现 Delayed 接口。 Delayed 接口是 Java 并发包中的一个接口,它扩展了 Comparable 接口,主要用于定义具有特定延迟时间的元素,这些元素可以被放入 DelayQueue 中。

Delayed 接口的主要目的是提供两个核心方法:

  1. getDelay: 这个方法返回元素的剩余延迟时间,即从当前时间到元素应该被处理的时间点之间的时间差。它接受一个 TimeUnit 参数,用于指定返回延迟时间的单位。
  2. compareTo: 这个方法用于比较两个 Delayed 对象,以确定它们的相对顺序。DelayQueue 根据这些对象的剩余延迟时间来维护队列的顺序,确保最早到期的元素最先被取出。

当你创建一个元素并将其放入 DelayQueue 时,你必须确保该元素实现了 Delayed 接口,并且正确地实现了 getDelaycompareTo 方法。这样,DelayQueue 才能根据元素的延迟时间来正确地排序和处理它们。

在上面的示例中,我们创建了一个名为 Data 的类,它实现了 Delayed 接口,并根据每个元素的延迟时间将其放入 DelayQueue 中。这样,DelayQueue 就能够按照元素的到期时间来安排它们的处理顺序。