BlockingQueueは、接続/リソースも追跡するため、よりシンプルです。
例えば
public abstract class ResourcePool<Resource> {
private final BlockingQueue<Resource> free;
protected ResourcePool(int freeLimit) {
free = new ArrayBlockingQueue<>(freeLimit);
}
public Resource acquire() {
Resource resource = free.poll();
return resource == null ? create() : resource;
}
public void recycle(Resource resource) {
if (!free.offer(resource))
close(resource);
}
protected abstract Resource create();
protected abstract void close(Resource resource);
}
ご覧のとおり、BlockingQueueは、空きリソースを追跡し、空きリソースが多すぎないようにするのに役立ちます。明示的なロックを必要とせずにスレッドセーフです。
セマフォを使用する場合でも、リソースをコレクションに保存する必要があります(セマフォを冗長にします;)