Java Reference
In-Depth Information
forward to fix this by joining to each thread before trying to use its result. Example 3-12
demonstrates.
Example 3-12. Avoid a race condition by joining to the thread that has a result you
need
import javax.xml.bind.DatatypeConverter ;
public class JoinDigestUserInterface {
public static void main ( String [] args ) {
ReturnDigest [] digestThreads = new ReturnDigest [ args . length ];
for ( int i = 0 ; i < args . length ; i ++) {
// Calculate the digest
digestThreads [ i ] = new ReturnDigest ( args [ i ]);
digestThreads [ i ]. start ();
}
for ( int i = 0 ; i < args . length ; i ++) {
try {
digestThreads [ i ]. join ();
// Now print the result
StringBuffer result = new StringBuffer ( args [ i ]);
result . append ( ": " );
byte [] digest = digestThreads [ i ]. getDigest ();
result . append ( DatatypeConverter . printHexBinary ( digest ));
System . out . println ( result );
} catch ( InterruptedException ex ) {
System . err . println ( "Thread Interrupted before completion" );
}
}
}
}
Because Example 3-12 joins to threads in the same order as the threads are started, this
fix also has the side effect of printing the output in the same order as the arguments
used to construct the threads, rather than in the order the threads finish. This modifi‐
cation doesn't make the program any slower, but it may occasionally be an issue if you
want to get the output of a thread as soon as it's done, without waiting for other unrelated
threads to finish first.
Joining is perhaps not as important as it was prior to Java 5. In partic‐
ular, many designs that used to require join() can now more easily be
implemented using an Executor and a Future instead.
Search WWH ::




Custom Search