loo*_*ese 9 java concurrency object-pooling
以下基本对象池是否有效?我有一个更复杂的基于相同的想法(即保持信号量和BlockingQueue).我的问题是 - 我需要Semaphore和BlockingQueue吗?我是对的,我不需要做任何同步吗?
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();
}
}
Run Code Online (Sandbox Code Playgroud)
sjl*_*lee 15
正如已经指出的那样,单独一个有界的BlockingQueue就足够了.例如,以下代码将执行您想要的操作:
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);
}
}
Run Code Online (Sandbox Code Playgroud)
此外,您可能需要考虑使用BlockingQueue.poll()支持borrow()的定时版本.
如果您没有有界阻塞队列数据结构,则可以在任何数据结构之上施加信号量以创建线程安全和绑定行为.
一个有点修改的sjlee的例子; 允许按需创建昂贵的对象.我的情况不需要任何阻塞工具,因此我用非阻塞队列类型替换它.作为一个好处,没有必要处理InterruptedExceptions.
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
}
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
13356 次 |
| 最近记录: |