这个基本的Java对象池是否有效?

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()的定时版本.

如果您没有有界阻塞队列数据结构,则可以在任何数据结构之上施加信号量以创建线程安全和绑定行为.


min*_*das 6

一个有点修改的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)


Tob*_*rre 0

也许你应该检查对象是否存在,这是我唯一拥有的东西。

编辑:我没有仔细阅读代码。所以我对帖子做了一些编辑。:(