From eeea3c7b1f37b8b2520acd6bc21fc0890161061d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ilkka=20Sepp=C3=A4l=C3=A4?= Date: Sat, 18 Jul 2020 10:51:02 +0300 Subject: [PATCH] #590 add explanation for Object Pool --- object-pool/README.md | 98 +++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 98 insertions(+) diff --git a/object-pool/README.md b/object-pool/README.md index efbf692ae..a8a20638c 100644 --- a/object-pool/README.md +++ b/object-pool/README.md @@ -15,6 +15,104 @@ short periods of time it is advantageous to utilize the Object Pool pattern. The Object Pool provides a cache for instantiated objects tracking which ones are in use and which are available. +## Explanation + +Real world example + +> In our war game we need to use oliphaunts, massive and mythic beasts, but the problem is that they are extremely expensive to create. The solution is to create a pool of them, track which ones are in-use, and instead of disposing them re-use the instances. + +In plain words + +> Object Pool manages a set of instances instead of creating and destroying them on demand. + +Wikipedia says + +> The object pool pattern is a software creational design pattern that uses a set of initialized objects kept ready to use – a "pool" – rather than allocating and destroying them on demand. + +**Programmatic Example** + +Here's the basic Oliphaunt class. These are very expensive to create. + +```java +public class Oliphaunt { + + private static AtomicInteger counter = new AtomicInteger(0); + + private final int id; + + public Oliphaunt() { + id = counter.incrementAndGet(); + try { + Thread.sleep(1000); + } catch (InterruptedException e) { + e.printStackTrace(); + } + } + + public int getId() { + return id; + } + + @Override + public String toString() { + return String.format("Oliphaunt id=%d", id); + } +} +``` + +Next we present the Object Pool and more specifically Oliphaunt Pool. + +```java +public abstract class ObjectPool { + + private Set available = new HashSet<>(); + private Set inUse = new HashSet<>(); + + protected abstract T create(); + + public synchronized T checkOut() { + if (available.isEmpty()) { + available.add(create()); + } + var instance = available.iterator().next(); + available.remove(instance); + inUse.add(instance); + return instance; + } + + public synchronized void checkIn(T instance) { + inUse.remove(instance); + available.add(instance); + } + + @Override + public synchronized String toString() { + return String.format("Pool available=%d inUse=%d", available.size(), inUse.size()); + } +} + +public class OliphauntPool extends ObjectPool { + + @Override + protected Oliphaunt create() { + return new Oliphaunt(); + } +} +``` + +And finally here's how we utilize the pool. + +```java + var pool = new OliphauntPool(); + var oliphaunt1 = pool.checkOut(); + var oliphaunt2 = pool.checkOut(); + var oliphaunt3 = pool.checkOut(); + pool.checkIn(oliphaunt1); + pool.checkIn(oliphaunt2); + var oliphaunt4 = pool.checkOut(); + var oliphaunt5 = pool.checkOut(); +``` + ## Class diagram ![alt text](./etc/object-pool.png "Object Pool")