私は長時間実行されているコードを持っていますが、それはリクエストでボロボロになり、リソースの使用率が高くなり、不要な同時実行の問題が発生します。
スロットルを使用する必要があるように思えExecutorService
ます。スレッドの数を固定し、新しいリクエストが来るたびに新しいスレッドが作成されないようにする必要があります。その後、プール内のスレッドの数を調整することで、スループットを最大化できます。
// only allow 10 concurrent requests
ExecutorService threadPool = Executors.newFixedThreadPool(10);
...
while (requestsComeIn) {
threadPool.submit(yourRunnableRequest);
}
// you need to shut the pool down once no more requests come in
threadPool.shutdown();
リクエストを調整するには、RejectedExecutionHandler
. 次のコードのようなものは、100 個の要素がキューに入った後にどのブロックが機能するかを示しています。
BlockingQueue<Runnable> queue = new ArrayBlockingQueue<Runnable>(100);
ThreadPoolExecutor threadPool =
new ThreadPoolExecutor(10, 10, 0L, TimeUnit.MILLISECONDS, queue);
// we need our RejectedExecutionHandler to block if the queue is full
threadPool.setRejectedExecutionHandler(new RejectedExecutionHandler() {
@Override
public void rejectedExecution(Runnable r, ThreadPoolExecutor executor) {
try {
// this will block the producer until there's room in the queue
executor.getQueue().put(r);
} catch (InterruptedException e) {
throw new RejectedExecutionException(
"Unexpected InterruptedException", e);
}
}
});
私の解決策は、各スレッドが事前に定義された時間だけ待機する待機領域のようなものを用意することです。
で無料で入手できますThreadPoolExecutor
。たとえば、1 つのコア スレッドと 10 の最大スレッドを割り当ててから、(たとえば) 指定し5L, TimeUnit.MINUTES
て、5 つの余分なスレッドの 1 つが 5 分間休止状態の場合、シャットダウンすることができます。残念ながら、キューがいっぱいでない限りThreadPoolExecutor
、はコア スレッドを超えて起動しないことに注意してください。したがって、キューに 100 個のものが入った後でのみ、2 番目のスレッドが割り当てられます。そのため、私は通常、core と max thread params を同じ値にします。