There is a more subtle performance recommendation here as well: carefully consider the
point at which the recursion for the fork/join paradigm should end. In this example, I've ar-
bitrarily chosen it to end when the array size is less than 10. If I'd stopped the recursion
when the array size was 2.5 million, then the fork/join test (specifically for the balanced code
processing a 10-million element array on a four-CPU machine) would have created only four
tasks, and its performance would have been essentially the same as that of the
On the other hand, continuing the recursion in the unbalanced test gives even better perform-
ance for that case, even though it creates yet more tasks—some representative data points for
that are shown in Table 9-6 .
Table 9-6. Time to process an array of 10,000 elements
Target size of leaf array ForkJoinPool
Java 8 introduces the ability for Java to automatically parallelize certain kinds of code. This
parallelization relies on the use of the ForkJoinPool class. Java 8 adds one new feature to
that class: a common pool that can be used by any ForkJoinTask that is not explicitly sub-
mitted to a specified pool. The common pool is a static element of the ForkJoinPool class,
and by default it is sized to the number of processors on the target machine.
This parallelization occurs in many new methods of the Arrays class: methods to sort an ar-
ray using parallel quicksorting, methods to operate on each individual element of an array,
and so on. It is also used within the Java 8 streams feature, which allows for operations
(either sequential or parallel) to be performed on each element in a collection. Some basic
performance implications of streams are discussed in Chapter 12 ; in this section, we'll look
at how streams can automatically be processed in parallel.