Does the following basic object pool work? I have a more sophisticated one based on the same idea (i.e. maintaining both a Semaphore and a BlockingQueue). My question is - do I need both Semaphore and BlockingQueue? Am I right that I don't need to do any synchronisation?
import java.util.Collection;
import java.util.concurrent.ArrayBlockingQueue;
import java.util.concurrent.BlockingQueue;
import java.util.concurrent.Semaphore;
public final class Pool<T> {
private final BlockingQueue<T> objects;
private final Semaphore permits;
public Pool(Collection<? extends T> objects) {
// we have as many permits as objects in our pool:
this.permits = new Semaphore(objects.size());
this.objects = new ArrayBlockingQueue<T>(objects.size(), false, objects);
}
public T borrow() {
this.permits.acquireUninterruptibly();
// we have a permit, so there must be one in there:
return this.objects.poll();
}
public void giveBack(T object) {
this.objects.add(object);
this.permits.release();
}
}
Maybe you should check that objects exists, that's the only thing I have.
Edit: I didn't read the code that carefully. So I edtied the post a bit. :(
A somewhat modified sjlee's example; allowing creation of expensive objects on demand. My case did not require any blocking facility hence I have replaced this with non-blocking queue type. As a benefit, there's no need to deal with InterruptedExceptions.
Maybe use a stack instead of a queue? This gives a chance of getting an object that is still sitting in the processor cache.
Here is one more simple and complete pool for latter one. It's better than the simplest, and it's simple.
From here
Its worth nothing that an ArrayBlockingQueue creates an object when you take an entry from it. So your pool won't actually save objects. It could only help if your objects are expensive to create.
Use take() instead of poll(), and put() instead of add(). The semaphore is then completely redundant so you can just get rid of it. But yes, that looks good.