Advanced Java Services | DelayQueue |
An unbounded blocking queue of Delayed elements, in which an element can only be taken when its delay has expired. The head of the queue is that Delayed element whose delay expired furthest in the past. If no delay has expired there is no head and poll will return null. Expiration occurs when an element's getDelay(TimeUnit.NANOSECONDS) method returns a value less than or equal to zero. Even though unexpired elements cannot be removed using take or poll, they are otherwise treated as normal elements. For example, the size method returns the count of both expired and unexpired elements. This queue does not permit null elements.
Eine DelayQueue arbeitet mit Elementen vom Typ Delayed.
public interface Delayed extends Comparable<Delayed> { long getDelay(TimeUnit unit); }
Da sich das Interface von Comparable ableitet sind zwei Methoden zu implementieren: compareTo() und getDelay().
Eine DelayQueue kann nur Objekte aufnehmen deren Klasse das Interface Delayed implementiert hat.
Diese Klasse sollte die Methoden compareTo() und getDelay() sinnvoll implementieren da die DelayQueue diese
beiden Methoden zum Aufbau wie zum Abbau der Queue verwendet.
Die DelayQueue ermittelt über compareTo() welches Element an der Spitze (Head) der Schlange stehen muß. Meist ist diese
das Element mit der kleinsten Delayzeit.
Eine DelayQueue kann beliebig viele Elemente aufnehmen. Das Headelement - und nur dieses - kann entnommen werden
falls getDelay() eine Zahl <= 0 liefert. Die Delayzeiten der anderen Elemente spielen dabei keine Rolle. Nach
einer Entnahme muß Delayqueue ein neues Headelement bestimmen.
Throws exception | Special value | Blocks | Times out | |
Insert | add(E e) | offer(E e) | put(E e) | offer(E e, long timeout, TimeUnit unit) |
Remove | remove() | poll() | take() | poll(long timeout, TimeUnit unit) |
Examine | element() | peek() | not applicable | not applicable |
element() und peek() werden bereits in AbstractQueue realisiert, wobei element() sich auf peek() stützt.
Bei einer DelayQuue werden add() und put() einfach mit offer() realisiert:
public boolean add(E e) { return offer(e); } public void put(E e) { offer(e); }
take() blockiert, verwendet aber bei einer Entnahme intern poll().
Hier hat die Delayzeit die Einheit Sekunden. In getDelay() muß das in Nanosekunden umgerechnet werden
class DelayedElement implements Delayed { int delay; // seconds public DelayedElement(int delay) { this.delay = delay; } @Override // Interface Comparable public int compareTo(Delayed de) { return this.delay - ((DelayedElement) de).delay; // Element mit der kleinsten Wartezeit wird Head } @Override // Interface Delayed // TimeUnit ist bei DelayQueue immer TimeUnit.NANOSECONDS public long getDelay(TimeUnit unit) { return delay * 1000 * 1000 * 1000; // Umrechnung der Sekunden in Nanos } // get/set-Methoden }
Auszug Quellcode von take()
for (;;) { //... long delay = first.getDelay(TimeUnit.NANOSECONDS); //... available.awaitNanos(delay); // }