ドキュメント上に読んでThreadPoolExecutor、私は違いが例の使用法に次の間でどのような混乱しています:
ゼロコアスレッドと10最大スレッド、2秒後にタイムアウトの後者回:
ThreadPoolExecutor executor = new ThreadPoolExecutor(
0, // core threads
10, // max threads
2000, TimeUnit.MILLISECONDS,
new LinkedBlockingQueue<Runnable>(),
Executors.defaultThreadFactory()
);
テンコアスレッドと10最大スレッドその2秒後にアウトの両方の時間:
ThreadPoolExecutor executor = new ThreadPoolExecutor(
10, // core threads
10, // max threads
2000, TimeUnit.MILLISECONDS,
new LinkedBlockingQueue<Runnable>(),
Executors.defaultThreadFactory()
);
executor.allowCoreThreadTimeOut(true);
これらの執行はどのような方法で異なる動作をしますか。
あなたは、モチベーションを読むことができるここに。
私は、固定されたスレッドプール(Executors.newFixedThreadPool())のようなものをしたいが、彼らが再び必要なときにスレッドが、彼らはあまりにも長い間アイドル状態にあるときにオフに死ぬ、と再作成したと。
最も直感的なアプローチ - セットコア0のサイズ、境界値に対する最大プールサイズ、および[アンバウンド形式のキュー]にキューが - 失敗:何のタスクがまったく実行されません取得(一貫Javadocのではなく - IMHO - 少し反し) 。
executor.allowCoreThreadTimeOut(true);
この動作を取得するために使用することができます。
あれば何のタスクはまったく実行されません取得する理由詳細corePoolSize = 0
指定されています
Javadocから、
(たとえば、事前に定義能力のないLinkedBlockingQueue)アンバウンド形式のキューを使用すると、すべてのcorePoolSizeスレッドがビジー状態のときに新しいタスクがキューで待機するようになります。したがって、これ以上のcorePoolSizeスレッドよりも、これまで作成されません。(そして、maximumPoolSizeの値は、したがって、任意の効果はありません。)
したがって、あなたが指定しない場合はcorePoolSize = 0
何のスレッドを今まで作成され、何のタスクはまったく実行されません。
しかし実際には、 corePoolSizeがゼロの場合、実装は(日JDK6とOpenJDK11でテスト済み)1つのスレッドを作成しません。だから、実際には、タスクがされているにかかわらず、何の、実行されますが、何の複数のスレッドがこれまでに作成されませんmaximumPoolSize
指定されています。私は、仕様に応じているので、それは一つも作成するべきではない理由を全くわかりません。
以下は私のテストコードです。これは今まで一つのスレッドを使用しますが、あなたが指定した場合corePoolSize=10
、それは10を追加した場合に使用するallowCoreThreadTimeOut(true)
、そしてこれらのスレッドがタイムアウトすることができます。
LinkedBlockingQueue<Runnable> q = new LinkedBlockingQueue<Runnable>();
ThreadPoolExecutor executor = new ThreadPoolExecutor(
0, // core threads
10, // max threads
2, TimeUnit.MILLISECONDS,
q
);
for (int i = 0; i < 10; i++) {
final int j = i;
executor.execute(() ->
{
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(
"TaskNo:" + j + ":" + Thread.currentThread().getName()
);
});
}
executor.shutdown();