ThreadPoolExecutorで、allowCoreThreadTimeOutゼロコアスレッド間の違いは何ですか?

ベニーBottema:

ドキュメント上に読んで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);

これらの執行はどのような方法で異なる動作をしますか。

Enno Shioji :

あなたは、モチベーションを読むことができるここに

私は、固定されたスレッドプール(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();

おすすめ

転載: http://43.154.161.224:23101/article/api/json?id=236138&siteId=1