以下是一个简单的 Java 代码示例,演示了如何使用 DelayQueue
来实现你的需求。在这个示例中,我们创建了一个 DelayQueue
对象,并启动了三个线程将三个数据对象(data1
、data2
、data3
)加入到延迟队列中,每个数据对象的延迟时间根据其索引计算。然后,我们启动了另外三个线程从延迟队列中执行 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
接口的主要目的是提供两个核心方法:
- getDelay: 这个方法返回元素的剩余延迟时间,即从当前时间到元素应该被处理的时间点之间的时间差。它接受一个
TimeUnit
参数,用于指定返回延迟时间的单位。 - compareTo: 这个方法用于比较两个
Delayed
对象,以确定它们的相对顺序。DelayQueue
根据这些对象的剩余延迟时间来维护队列的顺序,确保最早到期的元素最先被取出。
当你创建一个元素并将其放入 DelayQueue
时,你必须确保该元素实现了 Delayed
接口,并且正确地实现了 getDelay
和 compareTo
方法。这样,DelayQueue
才能根据元素的延迟时间来正确地排序和处理它们。
在上面的示例中,我们创建了一个名为 Data
的类,它实现了 Delayed
接口,并根据每个元素的延迟时间将其放入 DelayQueue
中。这样,DelayQueue
就能够按照元素的到期时间来安排它们的处理顺序。