Java還要再學一遍基礎(十六)- DelayQueue使用
阿新 • • 發佈:2019-01-04
概述
DelayQueue<E extends Delayed>Delayed 元素的一個無界阻塞佇列,只有在延遲期滿時才能從中提取元素。該佇列的頭部 是延遲期滿後儲存時間最長的 Delayed 元素。如果延遲都還沒有期滿,則佇列沒有頭部,並且 poll 將返回 null。當一個元素的 getDelay(TimeUnit.NANOSECONDS) 方法返回一個小於等於 0 的值時,將發生到期。即使無法使用 take 或 poll 移除未到期的元素,也不會將這些元素作為正常元素對待。
DelayQueue繼承自AbstractQueue,實現了BlockingQueue介面,內部維護了一個PriorityQueue的優先順序佇列,其中優先順序的判定是由過期時間來決定的。這也就完成了延時佇列的功能。
因此DelayQueue很適合用來做快取,Session等類似的功能。
使用
public interface Delayed extends Comparable<Delayed> {
long getDelay(TimeUnit unit);
}
getDelay方法返回與此物件相關的剩餘延遲時間,以給定的時間單位表示。
同時還需要實現compareTo方法用於優先順序佇列的比較工作。下面的程式簡單的演示了每隔一秒到期一個元素並輸出message。
輸出:public class DelayQueueDemo { public static void main(String[] args) throws InterruptedException { DelayQueue<DelayedNode> delayQueue = new DelayQueue<>(); final long start = System.nanoTime(); for (int i = 1; i <= 10; i++) { delayQueue.put(new DelayedNode(i + "", i, TimeUnit.SECONDS)); } while (!delayQueue.isEmpty()) { DelayedNode node = delayQueue.take(); System.out.println(node.getMessage() + "----> at " + (System.nanoTime() - start) / 1000 / 1000); } } static class DelayedNode implements Delayed { private final long expire; private final TimeUnit unit; private final String message; DelayedNode(String msg, int delay, TimeUnit timeUnit) { this.expire = System.nanoTime() + timeUnit.toNanos(delay); this.unit = timeUnit; this.message = msg; } @Override public int compareTo(Delayed o) { return this.getDelay(unit) > o.getDelay(unit) ? 1 : (this.getDelay(unit) == o.getDelay(unit) ? 0 : -1); } @Override public long getDelay(TimeUnit unit) { return unit.convert(expire - System.nanoTime(), TimeUnit.NANOSECONDS); } public String getMessage() { return message; } } }
1----> at 1005
2----> at 2007
3----> at 3016
4----> at 4011
5----> at 5016
6----> at 6016
7----> at 7017
8----> at 8004
9----> at 9004
10----> at 10013
注意:DelayQueue的size方法返回的個數同時包含了到期和未到期的個數。