design patterns ·
Object Pool
Maintains a pool of reusable objects to avoid the cost of creating and destroying them on demand.
Theory
Explanation
Intuition first, formal definition second. Skim the bullets if you already know this; read the prose if you don't.
Creating a database connection takes 50-100ms. If each request creates and destroys its own connection, throughput collapses. Pool pre-creates connections and lends them out - borrow when needed, return when done.
A pool holds a fixed set of pre-initialized objects. acquire() blocks until one is available; release() returns it to the pool. Java's BlockingQueue makes the blocking acquire/release trivial to implement.
When to use
Database connections, HTTP connections, thread pools, socket connections - any resource that is expensive to create and can be safely reused.
When not to
Cheap objects (strings, simple DTOs). Objects that cannot be reset to clean state between uses.
Key insights
- Pool size should match the expected concurrent demand - typically 10-20 for DB connections
- Leaked objects (acquired but never released) exhaust the pool and block all callers
- Try-with-resources or finally blocks ensure release even on exceptions
- HikariCP, c3p0, and DBCP implement this pattern for JDBC connections