Advanced   Java   Services DelayQueue Back Next Up Home


Aus der API

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.




Das Interface Delayed

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().


Eigenschaften

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.


Aufnehmen und Entnehmen
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 applicablenot 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().


Stub einer Klasse die das Interface Delayed implementiert

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
}

Das Zusammenspiel mit compareTo() und getDelay()

Auszug Quellcode von take()

for (;;)
{
   //...
   long delay = first.getDelay(TimeUnit.NANOSECONDS);
   //...
   available.awaitNanos(delay);
   //
}

Ueberschrift







Valid XHTML 1.0 Strict top Back Next Up Home