piątek, 24 sierpnia 2007

Producent-Konsument w Javie 5

Całkiem niedawno, przeglądając dokumentację API dla Java 1.5, odkryłem że pojawił się tam całkiem ciekawy mechanizm upraszczający rozwiązanie odwiecznego problemu Producenta - Konsumenta.

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
Korzystając z powyższych metod, przykładowa implementacja klas producenta i konsumenta może wyglądać tak (wg oficjalnej dokumentacją Javy):

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) { ... }
}

Brak komentarzy: