Using the New Concurrent Utility Classes in Java 5.0
java.util.concurrent package may just be your aspirin.
From its inception, Java has inherently supported multithreaded programming. But while that support was initially heralded, in practice it became apparent that writing high-performance multithreaded applications using only Java's limited built-in functionality was difficult. Coders often had to develop their own classes for common tasks such as monitoring thread progress or ensuring efficient and safe access to data. Doug Lea was one of those coders, and his openly available package of concurrent utilities for Java was so good that it's now being incorporated into the upcoming 5.0 (formerly 1.5) release of the language. In this article, we'll take a look at what Java had versus what it will have with the java.util.concurrent package, and examine an example that makes use of many of the new features that this package provides.
Java's pre5.0 support for threading was functional but limited, making it easy to ensure that data and data structures could be accessed safely across multiple threads, but doing little for performance. Other tasks, such as grouping threads, holding them at a certain point, starting or stopping them all at once, or allowing one to interrupt another, are impossible in pre5.0 Java releases without custom classes. With 5.0, those custom solutions should not be needed.
A Somewhat Complex Example
Rather than trying to cover all the new classes separately, let's take a look at an example that utilizes many of them, and I'll explain them as we go. Taking a cue from one of the most common hurdles facing coders working on multithreaded apps, the race condition (in which two threads compete to access a set of data), our example is a race simulator. But not the boring multithreaded data access kind of racerather, we'll look at a race featuring cars going around a track while being timed.
Our simulation isn't as flashy as a real car race, so you'll have to use your imagination, but it hits the important bits. We'll have a race with an arbitrary number of racer threads driving on a virtual circuit divided into three timing sectors. When the racer completes a sector, the exact time he crossed the line is recorded, the timing and scoring system updates his position relative to those of his opponents, and everyone's position will be viewed by thousands of spectator threads.
As you can imagine, there are a number of troubling scenarios here:
Multiple racers will be crossing sector boundaries in quick succession.
We can't have one racer stop while the system processes someone else's time.
We can't let the spectators' polling for updates affect the ability of the race to go on.
We need all the racers to start at the same time and stop when the leader has finished.
Plenty of potential issues, all easily tackled.