Building a Simple Java Object Pool with LinkedBlockingQueue and Factory Interface
This article describes how to build a lightweight custom object pool in Java using a LinkedBlockingQueue and a factory interface, detailing its design, implementation, code examples, and a test script that demonstrates borrowing, returning, and size control of pooled objects.
After studying commons-pool2 , the author found it too heavyweight for simple scenarios and decided to implement a lightweight custom object pool.
The design follows the ideas of commons-pool2 : use a queue to store cached objects, provide methods to borrow and return objects, and offer optional APIs to control pool size without enforcing them.
The implementation leverages Java's LinkedBlockingQueue for thread‑safe storage and a factory interface to create new instances, similar to Go's sync.Pool approach.
Code
package com.funtester.funpool
import java.util.concurrent.LinkedBlockingQueue
/**
* Object pool, using LinkedBlockingQueue to store objects, and using factory to create new objects, and using offer to return objects, and using poll to borrow objects, and using trimQueue to trim queue size
* @param
*/
class FunPool
{
/**
* Factory to create new objects
*/
FunPooledFactory
factory
/**
* Object pool, using LinkedBlockingQueue to store objects
*/
LinkedBlockingQueue
pool = new LinkedBlockingQueue
()
FunPool(FunPooledFactory
factory) {
this.factory = factory
}
/**
* Borrow an object from the pool
*
* @param o the object to be borrowed
* @return
*/
F borrow() {
F f = pool.poll()
if (f == null) {
f = factory.newInstance()
}
return f
}
/**
* Return the object to the pool
*
* @param f the object to be returned
*/
def back(F f) {
boolean offer = pool.offer(f)
if (!offer) f = null
}
/**
* return size of object pool
*
* @return
*/
int size() {
return pool.size()
}
/**
* Trim the queue size
* @param size the size to be trimmed
*/
def trimQueue(int size) {
while (true) {
if (size() <= size) break
pool.poll()
}
}
}The accompanying factory interface is defined as:
package com.funtester.funpool
/**
* Factory to create new objects
* @param
*/
interface FunPooledFactory
{
/**
* Create new objects
* @return
*/
F newInstance()
}The code walkthrough explains the core concepts: object‑pool design pattern, use of the factory pattern for flexible object creation, thread‑safety via LinkedBlockingQueue , borrowing and returning mechanisms, and queue size control through trimQueue() .
Test
A test script creates a pool of Demo objects, borrows and returns them, and prints the pool size, demonstrating that the same object is reused after being returned.
static void main(String[] args) {
def pool = new FunPool
(new FunPooledFactory
() {
@Override
Demo newInstance() {
return new Demo()
}
})
def first = pool.borrow()
println first.hashCode()
2.times {
def borrow = pool.borrow()
println borrow.hashCode()
pool.back(borrow)
}
output(pool.size())
}
/**
* A simple class
*/
static class Demo {
}The console output shows different hash codes for the first borrow and the subsequent two borrows, confirming that the pool reuses objects correctly.
Overall, this article provides a concise yet functional example of an object pool that can improve performance and resource utilization in Java applications.
FunTester
10k followers, 1k articles | completely useless
How this landed with the community
Was this worth your time?
0 Comments
Thoughtful readers leave field notes, pushback, and hard-won operational detail here.