A work queue coordinates the relationship between the producer and the consumer. When a new object is added to the queue, the message is sent to the consumer until the next message arrives in empty.
public class WorkQueue { LinkedList queue = new LinkedList(); // Add work to the work queue public synchronized void addWork(Object o) { queue.addLast(o); notify(); } // Retrieve work from the work queue; block if the queue is empty public synchronized Object getWork() throws InterruptedException { while (queue.isEmpty()) { wait(); } return queue.removeFirst(); }}
class Worker extends Thread { // Special end-of-stream marker. If a worker retrieves // an Integer that equals this marker, the worker will terminate. static final Object NO_MORE_WORK = new Object(); WorkQueue q; Worker(WorkQueue q) { this.q = q; } public void run() { try { while (true) { // Retrieve some work; block if the queue is empty Object x = q.getWork(); // Terminate if the end-of-stream marker was retrieved if (x == NO_MORE_WORK) { break; } // Compute the square of x int y = ((Integer)x).intValue() * ((Integer)x).intValue(); } } catch (InterruptedException e) { } }}
// Create the work queueWorkQueue queue = new WorkQueue();// Create a set of worker threadsfinal int numWorkers = 2;Worker[] workers = new Worker[numWorkers];for (int i=0; i<workers.length; i++) { workers[i] = new Worker(queue); workers[i].start();}// Add some work to the queue; block if the queue is full.// Note that null cannot be added to a blocking queue.for (int i=0; i<100; i++) { queue.addWork(i);}// Add special end-of-stream markers to terminate the workersfor (int i=0; i<workers.length; i++) { queue.addWork(Worker.NO_MORE_WORK);}