Java Reference
In-Depth Information
To ensure that your test actually tests what you think it does, it is important that the check-
sums themselves not be guessable by the compiler. It would be a bad idea to use consecutive
integers as your test data because then the result would always be the same, and a smart com-
piler could conceivably just precompute it.
To avoid this problem, test data should be generated randomly, but many otherwise effective
tests are compromised by a poor choice of random number generator (RNG). Random num-
ber generation can create couplings between classes and timing artifacts because most ran-
dom number generator classes are threadsafe and therefore introduce additional synchroniz-
Rather than using a general-purpose RNG, it is better to use simple pseudorandom functions.
You don't need high-quality randomness; all you need is enough randomness to ensure the
is among the cheapest mediumquality random number functions. Starting it off with values
based on
hashCode
and
nanoTime
makes the sums both unguessable and almost always
different for each run.
Listing 12.4. Medium-quality random number generator suitable for testing.
PutTakeTest
in
Listings 12.5
and
12.6
starts
N
producer threads that generate elements
and enqueue them, and
N
consumer threads that dequeue them. Each thread updates the
checksum of the elements as they go in or out, using a perthread checksum that is combined
at the end of the test run so as to add no more synchronization or contention than required to
test the buffer.
Depending on your platform, creating and starting a thread can be a moderately heavyweight
operation. If your thread is short-running and you start a number of threads in a loop, the
threads run sequentially rather than concurrently in the worst case. Even in the not-quite-
worst case, the fact that the first thread has a head start on the others means that you may
get fewer interleavings than expected: the first thread runs by itself for some amount of time,