Thread creation, scheduling, and destruction—all of these are costly—and they take a substantial amount of computation. Creating threads on demand and destroying them once they have finished their tasks is an inefficient way to organize a multi-threaded computation.
Thread pools are used to solve this problem. Each thread in the pool repeatedly waits for a task, a short-lived unit of computation. The thread is reused, executes a task, and then goes back to the pool to await the next one.
We implemented our own thread pool and used it to exercise the driver. Then, we had a detailed look at the fork-join API and studied how it uses work stealing.
We looked at the active object design pattern next, showing you how the idea is to hide the internal concurrency using a proxy.
We also touched upon the map-reduce theme and introduced concurrent hashing. We will be taking a closer look at this fascinating data structure in the next chapter! Stay tuned.