キャッシュされたスレッドプールを作成したいが、固定されたスレッドプールを作成する。現在、私はこのコードを持っている:私は、コードを実行した場合スレッドプールのサイズが変更されない
public class BackgroundProcesses {
public static void main(String[] args) throws InterruptedException, ExecutionException {
//ExecutorService threadPool2 = Executors.newCachedThreadPool();
ExecutorService threadPool = new ThreadPoolExecutor(2, 10, 180, TimeUnit.SECONDS, new LinkedBlockingQueue<>());
for (int i = 0; i < 800; i++) {
Callable<String> task = new Task();
threadPool.submit(task);
}
}
}
class Task implements Callable<String> {
@Override
public String call() throws Exception {
Thread.sleep(100);
System.out.println(Thread.currentThread().getName() + " is ready");
return "";
}
}
私は出力を得る:
pool-1-thread-1 is ready
pool-1-thread-2 is ready
pool-1-thread-1 is ready
pool-1-thread-2 is ready
...
はわずか2スレッドがすべての作業をやっているし、新しいワーカースレッドがプールに追加されません意味します。タスクがキュー内で待機している場合(私の場合は最大10個)、スレッドプールがさらにスレッドを生成すべきではありませんか?
Executors.newCachedThreadPool()
は、最大スレッドの上限が実質的になく、corePoolSize
であるため、使用したくありません。応答性向上のために常にスレッドを準備したいと考えています。 1 -----
-----編集は答えのためにあなたのアレクセイありがとうございます。キューの容量を設定することで、期待どおりの動作をさせるようになりましたが、今は新しい問題があります。
バックグラウンドタスクの量は大きく異なります。ほとんどの場合0ですが、短期間に最大50の同時タスクを実行できます。これを処理する効率的な方法は何でしょうか?ほとんどのバックグラウンドタスクは短命(< 1秒)ですが、長寿命のタスク(> 1分)もいくつかあります。私はこのように私のスレッドプールを設定した場合
:
ExecutorService threadPool = new ThreadPoolExecutor(2, 10, 180, TimeUnit.SECONDS, new LinkedBlockingQueue<>(10));
私が最も可能性の高いピーク使用してRejectedExecutionExceptionを取得します。しかし、スレッドプールを次のように設定した場合:
ExecutorService threadPool = new ThreadPoolExecutor(2, 10, 180, TimeUnit.SECONDS, new LinkedBlockingQueue<>(200));
キューが最大にならないため、新しいワーカースレッドは追加されません。
CPUには少なくとも4つのコアがあるため、これは私の意見では無駄です。そして、ほとんどの場合、バックグラウンドタスク(アップタイムの80%)はほとんどないので、固定スレッドプールを維持することは、私の意見では無駄になります。
これをクリアしていただきありがとうございます。キューがいっぱいになり、すべてのアクティブなスレッドも使用されているので、今私はRejectedExecutionException(プールサイズ= 10、アクティブなスレッド= 10、キューに入れられたタスク= 10)を取得しています。 –