web-dev-qa-db-ja.com

Javaバインドされたキューを持つスレッドプール

Java.util.concurrentの-​​ Executors クラスを使用して、Webサーバーの要求ハンドラーを実行するための固定スレッドプールを作成しています。

static ExecutorService  newFixedThreadPool(int nThreads) 

そして説明は:

共有unboundedキューで動作する一定のスレッドセットを再利用するスレッドプールを作成します。

ただし、boundedキューを除いて、まったく同じことを行うスレッドプールの実装を探しています。そのような実装はありますか?または、固定スレッドプール用に独自のラッパーを実装する必要がありますか?

32
Amir Rachum

あなたがやりたいことは、おそらく ThreadPoolExecutor を使用して、新しい独自のExecutorServiceです。 ThreadPoolExecutorには、BlockingQueueを取得するコンストラクターがあり、使用する制限付きキューを取得するには、たとえば ArrayBlockingQueue 制限用に適切に構築されます。 RejectedExecutionHandler を含めて、キューがいっぱいになったときに何をするかを決定したり、ブロッキングキューへの参照を待機して、offerメソッドを使用したりすることもできます。

ここに小さな例があります:

BlockingQueue<Runnable> linkedBlockingDeque = new LinkedBlockingDeque<Runnable>(
    100);
ExecutorService executorService = new ThreadPoolExecutor(1, 10, 30,
    TimeUnit.SECONDS, linkedBlockingDeque,
    new ThreadPoolExecutor.CallerRunsPolicy());
38
lscoughlin

ThreadPoolexecutor を作成し、適切なBlockingQueue実装を渡します。例えばThreadPoolExecutorコンストラクターで ArrayBlockingQueue を渡して、目的の効果を得ることができます。

6
Suraj Chandran

ThreadPoolExecutorを作成するときに、制限付きのBlockingQueueとRejectedExecutionHandlerを指定して、制限に達したときの動作を制御できます。デフォルトの動作では、RejectedExecutionExceptionがスローされます。

独自のスレッドファクトリを定義して、スレッド名を制御し、それらをデーモンスレッドにすることもできます。

3
Peter Lawrey

これを Semaphore で解決しました。これは、ExecutorServiceに送信されるタスクを抑制するために使用します。

例えば:

int threadCount = 10;
ExecutorService consumerPool = Executors.newFixedThreadPool(threadCount);

// set the permit count greater than thread count so that we 
// build up a limited buffer of waiting consumers
Semaphore semaphore = new Semaphore(threadCount * 100); 

for (int i = 0; i < 1000000; ++i) {
    semaphore.acquire(); // this might block waiting for a permit 
    Runnable consumer = () -> {
       try {
          doSomeWork(i);
       } finally {
          semaphore.release(); // release a permit 
       }
    };
    consumerPool.submit(consumer);
}
3
lance-java