5

データベース接続プールなどのリソースプールを実装する場合。どの同時収集を使用しますか?BlockingQueueまたはSemaphore

の場合BlockingQueue、プロデューサー-コンシューマーデザインパターンと同様に、プロデューサーはすべての接続をキューに配置し、コンシューマーはキューから次に使用可能な接続を取得します。

の場合Semaphore、セマフォをプールサイズに指定し、プールサイズに達するまで許可を取得し、いずれかが許可を解放してリソースをプールに戻すのを待ちます。

どちらがよりシンプルで簡単ですか?そして、1つしか使用できず、他は使用できないシナリオは何ですか?

4

3 に答える 3

14

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は、空きリソースを追跡し、空きリソースが多すぎないようにするのに役立ちます。明示的なロックを必要とせずにスレッドセーフです。

セマフォを使用する場合でも、リソースをコレクションに保存する必要があります(セマフォを冗長にします;)

于 2012-09-04T15:52:38.073 に答える
1

多くのブロッキングキューは、とにかくセマフォで実装されています(そしておそらくミューテックス/ futex / CS)。私はオブジェクトストレージにブロッキングキューをよく使用します-動作するブロッキングキューができたら、なぜオブジェクトプールに他のものを使用するのですか?

于 2012-09-04T15:55:23.010 に答える
1

高度な接続プールの場合、おそらくどちらも使用しません。@PeterLawreyが指摘しているように、BlockingQueueは、すべてのリソースが最初に存在する単純なプールに最も適しています。ただし、オンデマンドでリソースを作成するなど、より複雑なことを行う場合は、追加の同時実行構造が必要になる可能性があります。その場合、最終的には単純な同期ブロックまたはロックを使用することになります。

于 2012-09-04T15:55:38.920 に答える