finally section would have run without the lock being held. The throw from wait() still
would have had to relock, even though the lock would be released promptly.
Example 9-14 Interrupting a wait()
synchronized(this) {
try {
} catch (interuptedException ie) {
} finally {
The Morning After
Well, now that we've done all that, we're ready to get back to some useful work, right? Not quite.
Threads are rather particular about how they're treated after cancellation. They want to be
pampered. They want to be joined or at least waited for after they clean up.
The point here is that you don't want to be starting up new threads until the old ones are truly gone.
What if you have global variables that you need properly initialized? What if there is shared data
that you don't want old and new threads sharing? If nothing else, it's nice to clean up memory
before making new demands. (We're assuming that you'll run the same code again in your
program. If you really only ran it once, you wouldn't need to be so careful.)
In the searcher example (Code Example 9-15) we have one global array of threads. It would not
do to start creating in new threads while the successful searcher was still busy killing off the old
losers. Instead, we must wait for all the threads to exit before we reinitialize and start over again.
Example 9-15 From the main() Method for Searcher Example
synchronized(this) {
// Protect threads[]
for (int i = 0; i < nSearchers; i++) {
threads[i] = new Thread(new Searcher(this, i));
for (int i = 0; i < nSearchers; i++) {
synchronized(this) {
t = threads[i];
// Searcher may use threads[]
We don't actually need the threads to exit. We merely need the threads to reach a point where they
will never change any shared data and we will never use them again. Instead of using join(),
the same effect could be accomplished by using a SingleBarrier.
Search WWH :
Custom Search
Previous Page
Multithreaded Programming with JAVA - Topic Index
Next Page
Multithreaded Programming with JAVA - Bookmarks