アイドル時keepAliveTimeが= 0のAVAスレッドプールThreadPoolExecutorは、より少数のコア糸糸端部より直ちに手段

今日は、私の同僚が突然の選択で、良いとnewFixedThreadPoolとnew​​CacheThreadPoolを発行言うスレッドプールを上げ、= 0固定サイズのスレッドプールkeepAliveTimeがは言っても、スレッドのアイドルは、直ちにので、リソースを節約スレッドを回復し、その後、別の同僚が言った、0を代表すると、回復したことがありません私はまた、多くのオンラインブログ、ああ、ああ材料は彼の暇な時間に恒久的に0手段スレッドを生き残ると言われているので、永久に生きているメモリ0を覚えています。何の実績のある、永続的な感じはありません-1だと思う同僚の前で文字通りある各波を研究し、分析した後、回収されていません。

ソースコードに目を通すとkeepAliveTimeが<0が直接であること、与えられていない見つけ、同僚は推測は-1リサイクルされていない直視して、どのように赤いマークが付いたコードのセクションに私に聞かないでください(コードを見て、以下に示す、間違っていますF12編集ページ独自のラベルスタイルがに行く書くことです。)

公共ThreadPoolExecutor(INT corePoolSize、
                              INT maximumPoolSize、
                              長いkeepAliveTimeが、
                              TimeUnitでユニット、
                              BlockingQueueの<Runnableを>ワークキュー、
                              ThreadFactory threadFactory、
                              のRejectedExecutionHandlerハンドラ){
        (corePoolSize <0 ||場合
            maximumPoolSize <= 0 ||
            maximumPoolSize <corePoolSize ||
            keepAliveTimeが<0)
            新しいIllegalArgumentExceptionをスローし();
        (ワークキュー== nullの|| threadFactory == nullの||ハンドラ== null)の場合
            新しい新しいNullPointerExceptionがスロー();
        this.acc = System.getSecurityManager()== nullの?
                ナル:
                AccessController.getContext();
        this.corePoolSize = corePoolSize;
        this.maximumPoolSize = maximumPoolSize;
        this.workQueue =ワークキュー;
        this.keepAliveTime =ユニット.toNanos(keepAliveTimeが);
        this.threadFactory = threadFactory;
        this.handler =ハンドラ;
    }
その後、1:30のkeepAliveTimeが使用はそれらを見つけられないでしょう見つけるコードがテストされた使用とkeepAliveTimeが= 0のカーネルスレッド数が回復しないセットに見つけ、背後同僚はもちろん、書籍によって複雑分野の記述があると言います

「新しいタスクの最長時間を待っている余分なアイドルスレッドなどcorePoolSize、keepAliveTimeがよりスレッドプールの大きい内のスレッドの数は、超過したスレッドがこの時間より後に終了するとき。ここでは0LにkeepAliveTimeがセット、手段過剰アイドルスレッドそのそれはすぐに終了します。」

同僚は混乱し始め、私が最初に見ていない、私はそれは間違っていると感じ、背中を再読み込み、このテキスト記述が言うことです発見した0である非コアスレッドkeepAliveTimeがコントロールの数の回復、スレッドの非コア数私たちは、コアが回収されると言うことではない、彼の暇な時間で回復します。

次のような結果を検証するために、我々は、コードをテストし、テストコードは次のようになります。

パッケージcom.xhs.concurrent.threaddemo.sync。
輸入java.util.concurrent.LinkedBlockingQueue;
輸入java.util.concurrent.ThreadPoolExecutor;
輸入java.util.concurrent.TimeUnit。
 
/ **
 * @author xuhanビルド2019年4月23日
 * /
publicクラスExecutorsDemo実装Runnableを{
 
    I = 0のプライベートint型。
 
    公共ExecutorsDemo(INT I){
        this.i = I。
    }
    パブリック静的無効メイン(文字列[] args){
        ThreadPoolExecutorキュータ=て、新しいThreadPoolExecutor(1,2,0、TimeUnit.SECONDS、新しいLinkedBlockingQueue <Runnableを>(1))。
        以下のために(INT I = 0; I <3; I ++){
            てexecutor.execute(新しいExecutorsDemo(I))。
        }
        一方、(TRUE){
            するSystem.out.println( "总线程数:" + executor.getPoolSize()+ "当前活跃线程数:" + executor.getActiveCount())。
            {試みる
                TimeUnit.SECONDS.sleep(1)。
            }キャッチ(InterruptedExceptionある電子){
                e.printStackTrace();
            }
        }
    }
    @Override
    公共ボイドラン(){
        System.out.printlnは( "私は=" + I + "スレッド=" +にThread.currentThread()のgetName()。)。
        IF(I> = 1){
            {試みる
                TimeUnit.SECONDS.sleep(1)。
                System.out.println(+ I + "スリープ1秒结束" "私は=")。
            }キャッチ(InterruptedExceptionある電子){
                e.printStackTrace();
            }
        } {他
            のtry {
                TimeUnit.SECONDS.sleep(3);
                のSystem.out.println(+ I + "私は=" "S SLEEP端を3。");
            }キャッチ(InterruptedExceptionあるE){
                E. printStackTrace();
            }
        }
    }
}
のセットのコアと非コアスレッドは、スレッド1、実行可能に1,3のキューの容量です。

まず、メインスレッド、キューを入力する第二、第三を作成して実行している非メインスレッドを作成することで、

出力は、

私は0スレッド=プール| 1-スレッドを= 1つの
= 2スレッドI =プール| 1 2スレッド。
スレッドの合計数:アクティブなスレッドの2現在の数:2
スレッドの合計数:アクティブなスレッドの2現在の数:2
I = 2 SLEEP 1つのSは終了
iは1スレッド=プール-1 = -thread-2
アクティブなスレッドの2現在の数:2スレッドの合計数
2:スレッドの合計数:アクティブなスレッドの2現在数
1スリープ1の終了= Iを
1つの電流:スレッドの合計数をアクティブなスレッドの数:1つの
スレッドの合計数:アクティブなスレッドの現在の数:1つの
。I = 0 S SLEEP端3
スレッドの合計数:アクティブなスレッドの現在の数:0
非コアがスレッドの数が終了したことがわかる後、キューにタスクタスクの終了後に、このような再入力キューとして、実施していき、あなたは他のコアスレッドが終了されている間、スレッドの総数は、1を減少さ見ることができる、スレッドの総数が減少していないが、スレッドのコア数であるアクティブなスレッドの数を減らすことが回収されないことを見出しました。ブック言うが正しいか、オンラインのブログのほとんどがkeepAliveTimeが= 0回復は永久的な矛盾ではないと言います。

あなたが回復カーネルスレッドを設定したい場合は、設定する必要があります

executor.allowCoreThreadTimeOut(真の);
しかし、それはkeepAliveTimeががそれ以外の場合は、例外がスローされます、仕事のために> 0でなければならないです!

(「コアスレッドがしなければならない新しいIllegalArgumentExceptionをスローし生きている時間を保つゼロでない持っている」);
問題を抱えて見た後、私はあなたが何かを指している願っていた場合は!ありがとうございます!
----------------
免責事項:この記事は「xuhangsong」元の記事CSDNのブロガーで、CC 4.0 BY-SAの著作権契約書に従って、元のソースのリンクと、この文を添付してください、再現。 。
オリジナルリンクします。https://blog.csdn.net/xuhangsong/article/details/89474989

公開された18元の記事 ウォンの賞賛588 ビュー103万+

おすすめ

転載: blog.csdn.net/hellozhxy/article/details/104503713