README.md 3.4 KB
Newer Older
1 2 3 4
---
layout: pattern
title: Object Pool
folder: object-pool
5
permalink: /patterns/object-pool/
M
Markus 已提交
6
categories: Creational
7
tags:
8
 - Game programming
9
 - Performance
10 11
---

I
Ilkka Seppälä 已提交
12 13 14 15
## Also known as

Resource Pool

16
## Intent
I
Ilkka Seppälä 已提交
17 18 19 20

When objects are expensive to create and they are needed only for 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.
21

22 23 24 25
## Explanation

Real world example

I
Ilkka Seppälä 已提交
26 27 28
> 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.   
29 30 31 32 33 34 35

In plain words

> Object Pool manages a set of instances instead of creating and destroying them on demand. 

Wikipedia says

I
Ilkka Seppälä 已提交
36 37
> 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.
38 39 40

**Programmatic Example**

I
Ilkka Seppälä 已提交
41
Here's the basic `Oliphaunt` class. These giants are very expensive to create.
42 43 44 45

```java
public class Oliphaunt {

I
Ilkka Seppälä 已提交
46
  private static final AtomicInteger counter = new AtomicInteger(0);
47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69

  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);
  }
}
```

I
Ilkka Seppälä 已提交
70
Next we present the `ObjectPool` and more specifically `OliphauntPool`.
71 72 73 74

```java
public abstract class ObjectPool<T> {

I
Ilkka Seppälä 已提交
75 76
  private final Set<T> available = new HashSet<>();
  private final Set<T> inUse = new HashSet<>();
77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109

  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<Oliphaunt> {

  @Override
  protected Oliphaunt create() {
    return new Oliphaunt();
  }
}
```

I
Ilkka Seppälä 已提交
110
Finally, here's how we utilize the pool.
111 112 113 114 115 116 117 118 119 120 121 122

```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();
```

I
Ilkka Seppälä 已提交
123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139
Program output:

```
Pool available=0 inUse=0
Checked out Oliphaunt id=1
Pool available=0 inUse=1
Checked out Oliphaunt id=2
Checked out Oliphaunt id=3
Pool available=0 inUse=3
Checking in Oliphaunt id=1
Checking in Oliphaunt id=2
Pool available=2 inUse=1
Checked out Oliphaunt id=2
Checked out Oliphaunt id=1
Pool available=0 inUse=3
```

140
## Class diagram
I
Ilkka Seppälä 已提交
141

142 143
![alt text](./etc/object-pool.png "Object Pool")

144
## Applicability
I
Ilkka Seppälä 已提交
145

146
Use the Object Pool pattern when
147

I
Ilkka Seppälä 已提交
148 149
* The objects are expensive to create (allocation cost).
* You need a large number of short-lived objects (memory fragmentation).