Browse Java Design Patterns & Enterprise Application Architecture

Implementing Object Pool in Java

Implement Object Pool in Java with bounded capacity, explicit reset rules, and leak-safe borrow and release mechanics.

Object pool: A bounded collection of reusable resource objects that clients borrow, use briefly, reset, and return instead of constructing or tearing them down repeatedly.

In Java, Object Pool is only worth implementing when the pooled thing is genuinely expensive, scarce, or externally limited. Database connections, native buffers, parser instances with costly setup, and a few specialized infrastructure objects can fit. Ordinary domain objects usually do not.

Start With The Resource Contract

Before writing a pool, define three things:

  • what it means to borrow an instance
  • what state must be reset before reuse
  • what happens when the pool is empty

That contract matters more than the queue implementation.

A Small Bounded Pool

 1import java.time.Duration;
 2import java.util.concurrent.ArrayBlockingQueue;
 3import java.util.concurrent.BlockingQueue;
 4import java.util.concurrent.TimeUnit;
 5
 6public final class ParserPool {
 7    private final BlockingQueue<JsonParser> available;
 8
 9    public ParserPool(int size) {
10        this.available = new ArrayBlockingQueue<>(size);
11        for (int i = 0; i < size; i++) {
12            available.add(new JsonParser());
13        }
14    }
15
16    public JsonParser borrow(Duration timeout) throws InterruptedException {
17        JsonParser parser = available.poll(timeout.toMillis(), TimeUnit.MILLISECONDS);
18        if (parser == null) {
19            throw new IllegalStateException("No parser available");
20        }
21        return parser;
22    }
23
24    public void release(JsonParser parser) {
25        parser.reset();
26        if (!available.offer(parser)) {
27            throw new IllegalStateException("Pool overflow");
28        }
29    }
30}

The code is simple on purpose. A Java pool does not need cleverness first. It needs a correct lease boundary.

The flow below is the real lifecycle:

    flowchart LR
	    Client["Client"] --> Borrow["borrow()"]
	    Borrow --> Pool["Bounded pool"]
	    Pool --> Use["Use resource"]
	    Use --> Reset["reset()"]
	    Reset --> Release["release()"]
	    Release --> Pool

Reset Is The Hard Part

The main failure mode in object pools is not queue choice. It is state contamination between borrowers.

Reset logic should clear:

  • previous request data
  • buffers or cursors
  • authentication or tenant context
  • error flags and partial work state

If you cannot define a reliable reset routine, you probably should not pool the object.

Decide Saturation Behavior Explicitly

When the pool is empty, the code should not improvise. Choose one of these behaviors deliberately:

  • block until an instance becomes available
  • wait with timeout
  • fail fast
  • create a temporary overflow instance outside the normal pool

The right choice depends on latency goals, resource limits, and failure tolerance.

Borrow And Release Must Be Symmetric

Lease-based code should make return unavoidable:

1JsonParser parser = parserPool.borrow(Duration.ofMillis(200));
2try {
3    return parser.parse(payload);
4} finally {
5    parserPool.release(parser);
6}

That finally block is not optional. Without it, the pool quietly turns into a leak.

When To Prefer A Library

Many Java teams should not build a custom pool at all. For database access, HTTP connection reuse, thread execution, and common infrastructure concerns, mature libraries already solve capacity, monitoring, timeouts, and fault handling more safely than a homegrown pool.

Custom pools make sense when:

  • the pooled resource is domain-specific
  • the reset contract is well understood
  • a general-purpose library would add more abstraction than value

Design Review Questions

When reviewing a Java object pool, ask:

  • Is the pooled resource truly expensive or scarce?
  • Is reset behavior explicit and testable?
  • What happens under saturation?
  • How are leaked leases detected?

Object Pool is valid when it manages a real constrained resource. It is a smell when it exists only because “object creation is expensive” was copied from an old tutorial.

Revised on Thursday, April 23, 2026