Java Reference
In-Depth Information
Example 3-4. A main program that uses the accessor method to get the output of the
thread
import
javax.xml.bind.*
;
// for DatatypeConverter
public
class
ReturnDigestUserInterface
{
public
static
void
main
(
String
[]
args
)
{
for
(
String
filename
:
args
)
{
// Calculate the digest
ReturnDigest
dr
=
new
ReturnDigest
(
filename
);
dr
.
start
();
// Now print the result
StringBuilder
result
=
new
StringBuilder
(
filename
);
result
.
append
(
": "
);
byte
[]
digest
=
dr
.
getDigest
();
result
.
append
(
DatatypeConverter
.
printHexBinary
(
digest
));
System
.
out
.
println
(
result
);
}
}
}
The
ReturnDigest
class stores the result of the calculation in the private field
digest
,
which is accessed via
getDigest()
. The
main()
method in
ReturnDigestUserInter
face
loops through a list of files from the command line. It starts a new
ReturnDi
gest
thread for each file and then tries to retrieve the result using
getDigest()
. How‐
ever, when you run this program, the result may not be what you expect:
D:\JAVA\JNP4\examples\03>
java ReturnDigestUserInterface *.java
Exception in thread "main" java.lang.NullPointerException
at javax.xml.bind.DatatypeConverterImpl.printHexBinary
(DatatypeConverterImpl.java:358)
at javax.xml.bind.DatatypeConverter.printHexBinary(DatatypeConverter.java:560)
at ReturnDigestUserInterface.main(ReturnDigestUserInterface.java:15)
The problem is that the main program gets the digest and uses it before the thread has
had a chance to initialize it. Although this flow of control would work in a single-
threaded program in which
dr.start()
simply invoked the
run()
method in the same
thread, that's not what happens here. The calculations that
dr.start()
kicks off may or
may not finish before the
main()
method reaches the call to
dr.getDigest()
. If they
haven't finished,
dr.getDigest()
returns
null
, and the first attempt to access
digest
throws a
NullPointerException
.
Race Conditions
One possibility is to move the call to
dr.getDigest()
later in the
main()
method, like
this: