img
. .
request onto the queue, there is one less available slot, so we decrement the semaphore. When a
consumer takes a request off, there is one more, so we increment it.
Often, you will find that you have more extensive demands on the program and will need to use a
condition variable (wait/notify). Code Example 6-17 shows this situation. We will use the lock
from workpile to protect both the length of the list and the list itself,[13] so we remove the
locking from add() and remove() and do it in the producer and the consumer directly. (This
code now looks a little bit ugly with so many references to workpile, but we'll deal with that
later.) There is another little problem with this code, however.
[13]
We are using one lock to protect two things that must be changed atomically with respect to
each other. Any time we use either of those things, we must lock the same lock. You can never
protect a variable using two different locks.
Example 6-17 Classic Producer/Consumer Model (with a Tiny Bug)
public class Consumer implements Runnable {
...
public void run() {
Item item;
try {
while (true) {
synchronized (workpile) {
while (workpile.empty())
workpile.wait();
item = workpile.remove();
workpile.notify();
// Not quite
right
}
server.process(item);
}
} catch (InterruptedException e) {}
// Ignore for now
}
}
public class Producer implements Runnable {
public void run() {
Item item;
try {
while (true) {
item = server.get();
synchronized (workpile) {
while (workpile.full())
workpile.wait();
workpile.add(item);
workpile.notify();
// Not quite right
}
}
} catch (InterruptedException e) {}
// Ignore for now
}
}
Search WWH :
Custom Search
Previous Page
Multithreaded Programming with JAVA - Topic Index
Next Page
Multithreaded Programming with JAVA - Bookmarks
Home