Newsletter sign-up
View all newsletters

Enterprise Java Newsletter
Stay up to date on the latest tutorials and Java community news posted on JavaWorld

Sponsored Links

Optimize with a SATA RAID Storage Solution
Range of capacities as low as $1250 per TB. Ideal if you currently rely on servers/disks/JBODs

Programming Java threads in the real world, Part 4

Condition variables and counting semaphores -- filling in a few chinks in Java's threading model

  • Print
  • Feedback
This month's column adds a few more classes to the threading arsenal we started building in last month's Java Toolbox column. This time I'll discuss the following:

  1. Roll-your-own versions of the condition variable, which replaces wait() and notify() in some situations

  2. Djikstra's "counting" semaphore, which is used to manage pools of resources


(A semaphore is any of several mechanisms used to synchronize and communicate between threads. Think of the "semaphore" as in the flags that two boy scouts use to talk to each other from a distance -- different flag positions represent different letters of the alphabet. Napoleon's army used the vanes of windmills on mountain tops to send semaphore messages great distances very quickly. The mutex discussed last month, since it's a communications mechanism, is also a "semaphore.")

The condition variable can often be simulated using Java alone -- and I'll show you how -- while the counting semaphore can't.

Before I start, though, I'd like to go over a few loose ends from last month and fix a few bugs.

Oops! Could my code have bugs in it?

Before leaping into this month's meat (now there's a metaphor you can sink your teeth into), let's look at a few loose ends that either caught my eye (or were brought to my attention) after last month's article went live.

During one of my book's "peer reviews," an academic reviewer once took exception to the sentence "if you're anything like me, you'll forget to ... so you should write your code to do it automatically." His comment to me was: "I would never admit that in print." This guy was (and as far as I know, still is) a tenured professor at an Ivy League university, and I suppose his comment was correct in a literal sense: since he never had written any actual code, he never had any bugs to admit. I might as well say it up front, though: my code contains an occasional bug (gasp). Consequently, I expect an "Oops" section or its moral equivalent to become a regular feature of this column. There's nothing like having 100,000 people look over your code for problems to emerge and be highlighted.

Joe Bowbeer pointed out (quite correctly):

Why not advise the use of try/finally to prevent an exception from gunking up the works?

mutex.acquire();
try
{   doit();
}
finally
{   mutex.release();
}


I prefer the [above] form of try/finally because it separates the exceptions that might occur in changing the state (acquire) from the exceptions that might occur when working in the new state (doit).

The other (more intuitive?) form is

try
{   mutex.acquire();
    doit();
}
finally
{   mutex.release();
}


This requires more programming in release() to ensure that mutex is in a consistent state: if release() is called after an exception in acquire(), the mutex may not have been acquired, or [may have been] half-acquired, etc.



I should add that Joe's last point is important in the case of last month's Mutex class. The acquire_without_blocking() method, where the actual acquisition occurs, doesn't throw any exceptions at awkward times. The only exception that can be thrown from acquire(), in fact, is an InterruptedException, thrown if a timeout is specified and the waiting thread is interrupted. This operation does not leave the mutex in an unstable state, however.

  • Print
  • Feedback

Resources
  • All the real code discussed in this article (the stuff in the com.holub.asynch package) is available in the "Goodies" section on my Web site. The version on the Web site should be considered the definitive version -- at least it corrects any bugs I know about. http://www.holub.com