Java.util.concurrent
の- Executors
クラスを使用して、Webサーバーの要求ハンドラーを実行するための固定スレッドプールを作成しています。
static ExecutorService newFixedThreadPool(int nThreads)
そして説明は:
共有unboundedキューで動作する一定のスレッドセットを再利用するスレッドプールを作成します。
ただし、boundedキューを除いて、まったく同じことを行うスレッドプールの実装を探しています。そのような実装はありますか?または、固定スレッドプール用に独自のラッパーを実装する必要がありますか?
あなたがやりたいことは、おそらく 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());
ThreadPoolexecutor を作成し、適切なBlockingQueue実装を渡します。例えばThreadPoolExecutorコンストラクターで ArrayBlockingQueue を渡して、目的の効果を得ることができます。
ThreadPoolExecutorを作成するときに、制限付きのBlockingQueueとRejectedExecutionHandlerを指定して、制限に達したときの動作を制御できます。デフォルトの動作では、RejectedExecutionExceptionがスローされます。
独自のスレッドファクトリを定義して、スレッド名を制御し、それらをデーモンスレッドにすることもできます。
これを 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);
}