USERID_16091 Using blocking queues in Java 5 (in preference to wait/notify)   Javamex Home   Java synchronization   Java threads   Java profiling   Java I/O   NIO   Java collections   Home   Synchronization and concurrency   wait/notify   synchronized keyword   Java 5: ConcurrentHashMap   Atomic variables   Explicit locks   Queues   Semaphores The producer-consumer pattern in Java 5: using blocking queues in preference to wait() / notify() A common use for the wait/notify mechanism is to implement what is sometimes called a producer-consumer pattern. What is meant by this is that one thread "produces" work that another thread, or various other threads, then carry out at a convenient moment. Examples of this pattern include: a messaging thread logs messages "passed" to it from other threads; worker threads of a web server "notify" a statistics thread to update some central statistics on each request. A typical case for using the pattern is thus to separate tasks with different priorities . Logging, for example, can be a relatively expensive operation and we may not want it to delay completing another operation. By delegating logging to another thread, we can effectively allow logging to take place at a future moment when "there's nothing better to do". The producer-consumer pattern works by having some queue of pending tasks. The producer places tasks in the list; the consumer removes them. Both parties use suitable synchronization. Producer-consumer before Java 5: using a List with wait/notify Pre Java 5, the common way to implement a producer-consumer pattern was to use a plain old LinkedList with explicit synchronization. When we add a "job" to the list, we call notify() ; in another thread, the consumer is sitting wait ing for the job to come in. So the code would look something like this: public class LoggingThread extends Thread { private LinkedList linesToLog = new LinkedList(); private volatile boolean terminateRequested; public void run() { try { while (!terminateRequested) { String line; synchronized (linesToLog) { while (linesToLog.isEmpty()) linesToLog.wait(); line = (String) linesToLog.removeFirst(); } doLogLine(line); } } catch (InterruptedException ex) { Thread.currentThread().interrupt(); } } private void doLogLine(String line) { // ... write to wherever } public void log(String line) { synchronized (linesToLog) { linesToLog.add(line); linesToLog.notify(); } } } The code is a little messy because we have no explicit queue object: we just use an everyday list with code around it to perform the queuing. The queuing code might get more complex, for example, if we wanted to limit the number of items that could be queued, or if we wanted to prioritise items in the queue rather than having a simple first-in-first-out policy. The wait/notify mechanism also provides us no means of imposing fairness : that is, if two threads want to add a logging while the list is locked (because a line is being logged from it), which line gets logged first is essentially random. In the case of logging, this may not seem such a big deal (though in rare debugging cases could complicate things if you don't know "what happened first"). But in other cases it could matter more. The Java 5 producer-consumer pattern Java 5 improves the producer-consumer pattern by providing explicit blocking queue classes. A blocking queue effectively takes the place of the list in the code above, and also handles the associated synchronization, waiting and notifying (though under the hood, these new classes use the Java 5 lock features rather than a "raw" wait / notify ). On the next page, we continue by looking at Java blocking queues .   Did this article answer your question? If not, visit the new Javamex discussion forums to ask your question. Unless otherwise stated, the Java programming articles and tutorials on this site are written by Neil Coffey. Suggestions are always welcome if you wish to suggest topics for Java tutorials or programming articles, or if you simply have a programming question that you would like to see answered on this site. Most topics will be considered. But in particular, the site aims to provide tutorials and information on topics that aren't well covered elsewhere, or on Java performance information that is poorly described or understood. Suggestions may be made via the Javamex blog (see the site's front page for details). Copyright © Javamex UK 2009. All rights reserved.
iterasi archives home
Email Archive
Email the selected archives to as many people as you wish. You may include a message if you'd like.

TO:

MESSAGE:

Please enter the code word you see in the image to the right. If you cannot read the code, click Get New to display a new code.

CAPTCHA Code Image
Code:
  
Embed Code
You can embed a thumbnail and link to this archived page in your own page. Just copy and paste the html snippet below.

Short URL
Use the following short url for direct access to this archived page.



Archived page:

Using blocking queues in Java 5 (in preference to wait/notify)