这个基本的Java对象池工作吗?
以下基本对象池是否工作?我有一个基于相同想法的更复杂的方法(即同时维护信号量和阻塞队列)。我的问题是-我需要信号量和阻塞队列吗?我不需要做任何同步,对吗这个基本的Java对象池工作吗?,java,concurrency,object-pooling,Java,Concurrency,Object Pooling,以下基本对象池是否工作?我有一个基于相同想法的更复杂的方法(即同时维护信号量和阻塞队列)。我的问题是-我需要信号量和阻塞队列吗?我不需要做任何同步,对吗 import java.util.Collection; import java.util.concurrent.ArrayBlockingQueue; import java.util.concurrent.BlockingQueue; import java.util.concurrent.Semaphore; public final
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();
}
}
import java.util.Collection;
导入java.util.concurrent.ArrayBlockingQueue;
导入java.util.concurrent.BlockingQueue;
导入java.util.concurrent.Semaphore;
公开期末班{
私有最终阻塞队列对象;
专用最终信号量许可证;
公共池(集合也许你应该检查对象是否存在,这是我唯一拥有的东西
编辑:我没有仔细阅读代码。因此我对文章进行了一些编辑。(使用take()代替poll(),使用put()代替add())。然后,信号量是完全冗余的,因此您可以将其删除。但是,是的,这看起来不错。正如前面所指出的,仅使用有界阻塞队列就足够了。例如,以下代码将执行您想要的操作:
import java.util.Collection;
import java.util.concurrent.ArrayBlockingQueue;
import java.util.concurrent.BlockingQueue;
public final class Pool<T> {
private final BlockingQueue<T> objects;
public Pool(Collection<? extends T> objects) {
this.objects = new ArrayBlockingQueue<T>(objects.size(), false, objects);
}
public T borrow() throws InterruptedException {
return this.objects.take();
}
public void giveBack(T object) throws InterruptedException {
this.objects.put(object);
}
}
import java.util.Collection;
导入java.util.concurrent.ArrayBlockingQueue;
导入java.util.concurrent.BlockingQueue;
公开期末班{
私有最终阻塞队列对象;
公共游泳池(收集当您从ArrayBlockingQueue中获取条目时,ArrayBlockingQueue创建一个对象是毫无价值的。因此,您的池实际上不会保存对象。只有当您的对象创建成本很高时,它才有帮助。一个稍微修改过的sjlee示例;允许按需创建昂贵的对象。我的案例不需要任何阻塞工具因此,我将其替换为非阻塞队列类型。作为一个优点,不需要处理中断异常
import java.util.Collection;
import java.util.Queue;
import java.util.concurrent.ConcurrentLinkedQueue;
public abstract class ObjectPool<T> {
private final Queue<T> objects;
public ObjectPool() {
this.objects = new ConcurrentLinkedQueue<T>();
}
public ObjectPool(Collection<? extends T> objects) {
this.objects = new ConcurrentLinkedQueue<T>(objects);
}
public abstract T createExpensiveObject();
public T borrow() {
T t;
if ((t = objects.poll()) == null) {
t = createExpensiveObject();
}
return t;
}
public void giveBack(T object) {
this.objects.offer(object); // no point to wait for free space, just return
}
}
import java.util.Collection;
导入java.util.Queue;
导入java.util.concurrent.ConcurrentLinkedQueue;
公共抽象类对象池{
私有最终队列对象;
公共对象池(){
this.objects=新的ConcurrentLinkedQueue();
}
public ObjectPool(Collection可能使用堆栈而不是队列?这样就有机会获取仍位于处理器缓存中的对象。对于后者,这里有一个更简单、更完整的池。
它比最简单的好,而且很简单
从
/**
*
*@见简单池
*/
抽象静态类对象池
{
专用ConcurrentLinkedQueue池;
专用ScheduledExecutorService executorService;
/**
*创建池。
*
*@param minIdle池中驻留的最小对象数
*/
公共对象池(最终int-minIdle)
{
//初始化池
初始化(minIdle);
}
/**
*创建池。
*
*@param minIdle池中驻留的最小对象数
*@param maxIdle池中驻留的最大对象数
*@param validationInterval用于定期检查单独线程中的minIdle/maxIdle条件的时间(秒)。
*当对象数小于minIdle时,将创建缺少的实例。
*当对象数大于maxIdle时,将删除太多实例。
*/
公共对象池(最终int-minIdle、最终int-maxIdle、最终long-validationInterval)
{
//初始化池
初始化(minIdle);
//在单独的线程中检查池条件
executorService=Executors.newSingleThreadScheduledExecutor();
executorService.scheduleWithFixedDelay(新的Runnable()
{
@凌驾
公开募捐
{
int size=pool.size();
如果(尺寸<迷你)
{
int sizetobeaded=minIdle-size;
对于(int i=0;i最大空闲)
{
int sizeToBeRemoved=size-maxIdle;
对于(int i=0;i
您自己这么做的原因是什么?Apache Commons Pool现成就做了。ApacheCommonsPool提供了blockingQueue不提供的功能是什么?它引入了一个大型库来定义一组大型的“标准”当java.util.concurrent.BlockingQueue已经支持所有已定义的操作时的接口。@skaffman您可以帮助创建一个漂亮且清晰的示例-但我的选择是将池类抽象化而不是最终化,并添加一个abs
/**
*
* @see <a href=http://www.javacodegeeks.com/2013/08/simple-and-lightweight-pool-implementation.html>simple pool</>
*/
abstract static class ObjectPool<T>
{
private ConcurrentLinkedQueue<T> pool;
private ScheduledExecutorService executorService;
/**
* Creates the pool.
*
* @param minIdle minimum number of objects residing in the pool
*/
public ObjectPool(final int minIdle)
{
// initialize pool
initialize(minIdle);
}
/**
* Creates the pool.
*
* @param minIdle minimum number of objects residing in the pool
* @param maxIdle maximum number of objects residing in the pool
* @param validationInterval time in seconds for periodical checking of minIdle / maxIdle conditions in a separate thread.
* When the number of objects is less than minIdle, missing instances will be created.
* When the number of objects is greater than maxIdle, too many instances will be removed.
*/
public ObjectPool(final int minIdle, final int maxIdle, final long validationInterval)
{
// initialize pool
initialize(minIdle);
// check pool conditions in a separate thread
executorService = Executors.newSingleThreadScheduledExecutor();
executorService.scheduleWithFixedDelay(new Runnable()
{
@Override
public void run()
{
int size = pool.size();
if (size < minIdle)
{
int sizeToBeAdded = minIdle - size;
for (int i = 0; i < sizeToBeAdded; i++)
{
pool.add(createObject());
}
} else if (size > maxIdle)
{
int sizeToBeRemoved = size - maxIdle;
for (int i = 0; i < sizeToBeRemoved; i++)
{
pool.poll();
}
}
}
}, validationInterval, validationInterval, TimeUnit.SECONDS);
}
/**
* Gets the next free object from the pool. If the pool doesn't contain any objects,
* a new object will be created and given to the caller of this method back.
*
* @return T borrowed object
*/
public T borrowObject()
{
T object;
if ((object = pool.poll()) == null)
{
object = createObject();
}
return object;
}
/**
* Returns object back to the pool.
*
* @param object object to be returned
*/
public void returnObject(T object)
{
if (object == null)
{
return;
}
this.pool.offer(object);
}
/**
* Shutdown this pool.
*/
public void shutdown()
{
if (executorService != null)
{
executorService.shutdown();
}
}
/**
* Creates a new object.
*
* @return T new object
*/
protected abstract T createObject();
private void initialize(final int minIdle)
{
pool = new ConcurrentLinkedQueue<T>();
for (int i = 0; i < minIdle; i++)
{
pool.add(createObject());
}
}
}