Since Java SE 5.0, developing multithreaded applications became much easier due to the task executor framework. Instead of working with low level synchronization constructs, the framework introduces the concepts of Task and Executors. It also provides isolation between task submission and task execution, allowing to easily change execution policy without even touching submission logic. Still, it doesn’t save you from creating race conditions and other difficult to debug and discover bugs, so in order to use the framework to its full power, I recommend starting from basics. A great book that covers almost everything you need to know about multithreading in Java is Java Concurrency in Practice by Brian Goetz and it’s a must if you are developing in Java. In this article, I will show you how to create a useful utility class for managing a pool of expensive objects, and how simple it is to create complex structures by reusing what Java offers.
Imagine we are writing an online multiplayer game and we want to offer several players to play together a procedural generated level. Since the level generation is a very expensive operation, we do not want to affect our players experience and having them to wait too long for it to complete. Instead, we want to maintain a pool of already generated levels that we can offer immediately. Also, we want to support parallel creation of additional levels to maintain our cache full. With these things in mind, let’s create a reusable component that supports the operations we need.