DelayQueue 實現 BlockingQueue 接口。 DelayQueue 中的元素必須保留一定的時間。
DelayQueue 使用一個名為 Delayed 的接口來獲取延遲時間。
該接口在java.util.concurrent包中。 其聲明如下:
public interface Delayed extends Comparable {
long getDelay(TimeUnit timeUnit);
}
它擴展了 Comparable 接口,它的 compareTo()方法接受一個Delayed對象。
DelayQueue 調用每個元素的 getDelay()方法來獲取元素必須保留多長時間。 DelayQueue 將傳遞 TimeUnit 到此方法。
當 getDelay()方法返回一個零或一個負數時,是元素離開隊列的時間。
隊列通過調用元素的 compareTo()方法確定要彈出的那個。 此方法確定要從隊列中刪除的過期元素的優先級。
以下代碼顯示了如何使用DelayQueue。
import static java.time.temporal.ChronoUnit.MILLIS;
import static java.util.concurrent.TimeUnit.MILLISECONDS;
import java.time.Instant;
import java.util.concurrent.BlockingQueue;
import java.util.concurrent.DelayQueue;
import java.util.concurrent.Delayed;
import java.util.concurrent.TimeUnit;
class DelayedJob implements Delayed {
private Instant scheduledTime;
String jobName;
public DelayedJob(String jobName, Instant scheduledTime) {
this.scheduledTime = scheduledTime;
this.jobName = jobName;
}
@Override
public long getDelay(TimeUnit unit) {
long delay = MILLIS.between(Instant.now(), scheduledTime);
long returnValue = unit.convert(delay, MILLISECONDS);
return returnValue;
}
@Override
public int compareTo(Delayed job) {
long currentJobDelay = this.getDelay(MILLISECONDS);
long jobDelay = job.getDelay(MILLISECONDS);
int diff = 0;
if (currentJobDelay > jobDelay) {
diff = 1;
} else if (currentJobDelay < jobDelay) {
diff = -1;
}
return diff;
}
@Override
public String toString() {
String str = this.jobName + ", " + "Scheduled Time: "
+ this.scheduledTime;
return str;
}
}
public class Main {
public static void main(String[] args) throws InterruptedException {
BlockingQueue queue = new DelayQueue<>();
Instant now = Instant.now();
queue.put(new DelayedJob("A", now.plusSeconds(9)));
queue.put(new DelayedJob("B", now.plusSeconds(3)));
queue.put(new DelayedJob("C", now.plusSeconds(6)));
queue.put(new DelayedJob("D", now.plusSeconds(1)));
while (queue.size() > 0) {
System.out.println("started...");
DelayedJob job = queue.take();
System.out.println("Job: " + job);
}
System.out.println("Finished.");
}
}
上面的代碼生成以下結果。