Das Interface java.util.concurrent.BlockingDeque
erweitert das Deque-Interface um zusätzliche blockierende Operationen:
- Dequeue-Operationen, die beim Entnehmen eines Elements aus einem leeren Deque so lange warten, bis ein Element verfügbar ist (also darauf, dass ein anderer Thread eines einfügt).
- Enqueue-Operationen, die beim Einfügen eines Elements in ein volles¹ Deque so lange blockieren, bis wieder Platz verfügbar ist (also, bis ein anderer Thread ein Element entnommen hat).
BlockingDeque
erweitert außerdem BlockingQueue, und indirekt – sowohl über Deque
als auch über BlockingQueue
– die Queue- und Collection-Interfaces:
¹ Ein Deque ist voll, wenn es größenbeschränkt (bounded) ist und die Anzahl der in das Deque eingefügten Elemente die festgelegte Deque-Kapazität erreicht hat.
Java BlockingDeque-Methoden
Die blockierenden Methoden gibt es in jeweils zwei Varianten: eine, die unbegrenzt lange wartet und eine, der man einen Timeout mitgeben kann. Wenn dieser abläuft, bricht die Methode ab und liefert einen Fehlercode zurück.
Die Methoden, die BlockingDeque
von BlockingQueue
erbt (z. B. Einfügen am Ende, Entnahme am Kopf), wurden der Konsistenz halber mit neuen Namen zusätzlich definiert – beispielsweise BlockingQueue.put()
als BlockingDeque.putLast()
.
In der folgenden Auflistung der Methoden führe ich diese BlockingQueue
-Methoden jeweils bei den äquivalenten BlockingDeque
-Methoden mit an.
Am Ende des Kapitels findest du zwei Tabellen, in der noch einmal alle Methoden übersichtlich zusammengefasst sind.
Blockierende Methoden zum Einfügen in das Deque
Zunächst eine grafische Darstellung der blockierenden Enqueue-Methoden:
BlockingDeque.putFirst() + putLast()
Die Methoden putFirst()
und putLast()
fügen ein Element am Anfang bzw. Ende des Deques ein, sofern Platz vorhanden ist. Ist das Deque hingegen voll, blockieren diese Methoden so lange, bis ein anderer Thread ein Element entnommen hat und somit wieder Platz für das neue Element vorhanden ist.
Die vom BlockingQueue
-Interface geerbte Methode BlockingQueue.put()
wird zu BlockingDeque.putLast()
weitergeleitet.
BlockingQueue.offerFirst() + offerLast() mit Timeout
Auch offerFirst()
und offerLast()
fügen ein Element in das Deque ein, sofern Platz vorhanden ist. Andernfalls blockieren diese Methoden für maximal die angegebene Zeit. Konnte nach Ablauf dieser Zeit das Element nicht eingefügt werden, geben diese Methoden false
zurück.
Die vom BlockingQueue
-Interface geerbte Methode BlockingQueue.offer(E e, long timeout, TimeUnit unit)
wird zu BlockingDeque.offerLast(E e, long timeout, TimeUnit unit)
weitergeleitet.
Blockierende Methoden zum Entnehmen aus dem Deque
Zunächst wieder eine grafische Darstellung der blockierenden Dequeue-Methoden:
BlockingQueue.takeFirst() + takeLast()
takeFirst()
und takeLast()
entnehmen ein Element vom Anfang bzw. Ende des Deques, sofern das Deque nicht leer ist. Bei einem leeren Deque blockieren diese Methoden solange, bis ein anderer Thread ein Element einfügt.
Die vom BlockingQueue
-Interface geerbte Methode BlockingQueue.take()
wird zu BlockingDeque.takeFirst()
weitergeleitet.
BlockingQueue.pollFirst() + pollLast() mit Timeout
Auch pollFirst()
und pollLast()
entnehmen ein Element vom Deque, sofern eines verfügbar ist. Andernfalls warten die Methoden für die angegebene Zeit. Wenn innerhalb der Wartezeit ein Element eingefügt wird, liefern die Methoden es sofort zurück. Wenn nach Ablauf der Zeit noch immer kein Element vorhanden ist, geben diese Methoden null
zurück.
Die vom BlockingQueue
-Interface geerbte Methode BlockingQueue.poll(E e, long timeout, TimeUnit unit)
wird zu BlockingDeque.pollFirst(E e, long timeout, TimeUnit unit)
weitergeleitet.
BlockingDeque-Methoden – Zusammenfassung
Im folgenden findest du zwei Tabellen: die erste enthält die Methoden zum Einfügen und Entnehmen von Elementen am Kopf des Deques; die zweite enthält die Methoden für die Elemente am Ende des Deques.
In den ersten zwei Spalten siehst du jeweils die nicht blockierenden Methoden, die BlockingDeque
von Deque
(und indirekt von Queue
– diese sind mit einer hochgestellten 1 markiert) erbt.
In der dritten und vierten Spalte findest du jeweils die neuen, blockierenden Methoden (einschließlich derer, die in BlockingQueue
definiert sind – diese sind mit einer hochgestellten 2 markiert).
Operationen am Anfang (Kopf) des Deques
Nicht blockierend (geerbt von Deque ) | Blockierend (neu in BlockingDeque ) | |||
---|---|---|---|---|
Exception | Rückgabewert | Blockiert | Blockiert mit Timeout | |
Element anhängen (enqueue): | addFirst(E e) | offerFirst(E e) | putFirst(E e) | offerFirst(E e, |
Element entnehmen (dequeue): | removeFirst() ¹ | pollFirst() ¹ | takeFirst() ² | pollFirst( ² |
Element ansehen (examine): | getFirst() ¹ | peekFirst() ¹ | – | – |
Operationen am Ende des Deques
Nicht blockierend (geerbt von Deque ) | Blockierend (neu in BlockingDeque ) | |||
---|---|---|---|---|
Exception | Rückgabewert | Blockiert | Blockiert mit Timeout | |
Element anhängen (enqueue): | addLast(E e) ¹ | offerLast(E e) ¹ | putLast(E e) ² | offerLast(E e, ² |
Element entnehmen (dequeue): | removeLast() | pollLast() | takeLast() | pollLast( |
Element ansehen (examine): | getLast() | peekLast() | – | – |
¹ Diese Methoden sind im Queue
-Interface implementiert und rufen die entsprechenden Deque
-Methoden auf.
² Diese Methoden sind im BlockingQueue
-Interface implementiert und rufen die entsprechenden BlockingDeque
-Methoden auf.
Java BlockingDeque-Beispiel
Ein Beispiel für die Benutzung des BlockingDeque
-Interfaces findest du im Tutorial-Teil über die einzige Implementierung dieses Interfaces: LinkedBlockingDeque.
Zusammenfassung und Ausblick
In diesem Artikel hast du das BlockingDeque
-Interface und dessen blockierenden Methoden putFirst()
, putLast()
, offerFirst()
, offerLast()
, takeFirst()
, takeLast()
, und pollFirst()
, pollLast()
kennengelernt.
In den folgenden Teilen dieser Tutorialserie werde ich alle Deque
- und BlockingDeque
-Implementierungen mit ihren spezifischen Eigenschaften vorstellen. Am Ende findest du eine Empfehlung, wann du welche Implementierung einsetzen solltest. Zum Abschluss des Tutorials zeige ich dir, wie du selbst ein Deque in Java implementieren kannst.
Wenn du noch Fragen hast, stelle sie gerne über die Kommentar-Funktion. Möchtest du über neue Tutorials und Artikel informiert werden? Dann klicke hier, um dich für den HappyCoders.eu-Newsletter anzumelden.