Interfejs BlockingQueue, bo o nim mowa, reprezentuje typ synchronizowanej kolejki o zadanej pojemności. Udostępnia bardzo wygodne w użyciu metody wstawiania (add / offer / put) i pobierania obiektów (poll / take). Ich wygoda polega na ich różnorodności:
- put wstawia obiekt, czekając jeśli trzeba na zwolnienie miejsca w kolejce
- offer próbuje wstawić obiekt i zwraca true / false jako odpowiedź czy operacja się udała
- add wstawia obiekt do kolejki "na siłę" i ewentualnie rzuca IllegalStateException jeśli kolejka jest już pełna
- take pobiera obiekt z kolejki, czekając jeśli trzeba na pojawienie się obiektu w kolejce
- poll pobiera obiekt z kolejki lub null, jeśli upłynie określona ilość czasu a kolejka jest pusta
class Producer implements Runnable {
private final BlockingQueue queue;
Producer(BlockingQueue q) { queue = q; }
public void run() {
try {
while(true) { queue.put(produce()); }
} catch (InterruptedException ex) { ... }
}
Object produce() { ... }
}
class Consumer implements Runnable {
private final BlockingQueue queue;
Consumer(BlockingQueue q) { queue = q; }
public void run() {
try {
while(true) { consume(queue.take()); }
} catch (InterruptedException ex) { ... }
}
void consume(Object x) { ... }
}