1. The ForkJoinPool class should be used for recursive, divide-and-conquer al-
2. Make the effort to determine the best point at which the recursion of tasks in the
algorithm should cease. Creating too many tasks can hurt performance, but too
few tasks will also hurt performance if the tasks do not take the same amount of
3. Features in Java 8 that use automatic parallelization will use a common instance
of the ForkJoinPool class. You may need to adjust the default size of that com-
In a perfect world—or in examples for a topic—it is relatively easy for threads to avoid the
need for synchronization. In the real world, things are not necessarily so easy.
SYNCHRONIZATION AND JAVA CONCURRENT UTILITIES
In this section, when the term synchronization is used, it means code that is within a block where
access to a set of variables appears serialized: only a single thread at a time can access the
memory. This includes code blocks protected by the synchronized keyword. It also means code
that is protected by an instance of the java.util.concurrent.lock.Lock class, and code within
the java.util.concurrent and java.util.concurrent.atomic packages.
Strictly speaking, the atomic classes do not use synchronization, at least in CPU programming
terms. Atomic classes utilize a “Compare and Swap” (CAS) CPU instruction, while synchroniza-
tion requires exclusive access to a resource. Threads that utilize CAS instructions will not block
when simultaneously accessing the same resource, while a thread that needs a synchronization
lock will block if another thread holds that resource.
There are performance trade-offs between the two approaches (which are discussed later in this
section). However, even though CAS instructions are lockless and nonblocking, they still exhibit
most of the behavior of blocking constructs: their end result makes it appear to the developer that
threads can only access the protected memory serially.