ava thread pool ThreadPoolExecutor of keepAliveTime = 0, it means more than a few core thread thread ends immediately when idle

Today, my colleagues suddenly raised the issue say which thread pool with a good, newFixedThreadPool and newCacheThreadPool in the selection, said fixed-size thread pool keepAliveTime = 0, thread idle will immediately recover the thread thus saving resources, and then another colleague said, with 0 being the representative never recovered, I also remember the memory 0 is permanently alive, because many online blog, ah, ah materials are said to survive 0 means the thread permanently in his spare time. Is literally in front of colleagues who think there is no proven, permanent feel -1 is not recovered, then each wave were studied and analyzed.

Look through the source code and found keepAliveTime <0 is not directly given, that is, colleagues speculate -1 is not recycled is wrong, look at the code shown below (do not ask me how to code section marked red, with direct view F12 edit page is to write your own label styles go in ..)

public ThreadPoolExecutor(int corePoolSize,
                              int maximumPoolSize,
                              long keepAliveTime,
                              TimeUnit unit,
                              BlockingQueue<Runnable> workQueue,
                              ThreadFactory threadFactory,
                              RejectedExecutionHandler handler) {
        if (corePoolSize < 0 ||
            maximumPoolSize <= 0 ||
            maximumPoolSize < corePoolSize ||
            keepAliveTime < 0)
            throw new IllegalArgumentException();
        if (workQueue == null || threadFactory == null || handler == null)
            new new NullPointerException the throw ();
        ? this.acc = System.getSecurityManager () == null
                null:
                AccessController.getContext ();
        this.corePoolSize = corePoolSize;
        this.maximumPoolSize = maximumPoolSize;
        this.workQueue = workQueue;
        this.keepAliveTime = Unit .toNanos (keepAliveTime);
        this.threadFactory = threadFactory;
        this.handler = Handler;
    }
then find keepAliveTime use of 1:30 would not find them, use the code was tested and found to set keepAliveTime = 0 kernel thread count does not recover, behind colleagues say there is a description in the arts course complicated by the book

"When the number of threads in the thread pool greater than corePoolSize, keepAliveTime as excess idle threads waiting for new tasks longest time, excess threads will be terminated after more than this time. Here the keepAliveTime set to 0L, means that excess idle threads It will be terminated immediately. "

Colleagues began confused, I did not look at the beginning, I feel that's wrong, re-read the back and found this text description is to say that the recovery of the number of non-core thread keepAliveTime control, that is 0, the non-core number of threads We will recover in his spare time, not to say that the core will be recovered.

To verify the results, we tested with code, test code is as follows:

package com.xhs.concurrent.threaddemo.sync;
import java.util.concurrent.LinkedBlockingQueue;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;
 
/**
 * @author xuhan  build  2019/4/23
 */
public class ExecutorsDemo implements Runnable{
 
    private int i=0;
 
    public ExecutorsDemo(int i) {
        this.i = i;
    }
    public static void main(String[] args) {
        ThreadPoolExecutor executor = new ThreadPoolExecutor(1,2,0, TimeUnit.SECONDS,new LinkedBlockingQueue<Runnable>(1));
        for(int i=0;i<3;i++){
            executor.execute(new ExecutorsDemo(i));
        }
        while(true){
            System.out.println("总线程数:"+executor.getPoolSize()+"当前活跃线程数:"+executor.getActiveCount());
            try {
                TimeUnit.SECONDS.sleep(1);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }
    @Override
    public void run() {
        System.out.println("i="+i+" Thread = "+Thread.currentThread().getName());
        if(i>=1){
            try {
                TimeUnit.SECONDS.sleep(1);
                System.out.println("i="+i+" sleep 1 s结束");
            } catch (InterruptedException e) {
                e.printStackTrace ();
            }
        } {the else
            the try {
                TimeUnit.SECONDS.sleep (. 3);
                System.out.println ( "I =" + I + "S SLEEP end. 3");
            } the catch (InterruptedException E) {
                E. printStackTrace ();
            }
        }
    }
}
set core and non-core threads are threads 1, queue capacity of 1, 3 into the runnable:

First create the main thread, the second to enter the queue, and the third is to create a non-main thread running,

The output is

I = 0 the Thread = the pool-. 1-Thread-. 1
I = 2 the Thread = the pool-. 1 2-Thread-
total number of threads: 2 current number of active threads: 2
Total number of threads: 2 current number of active threads: 2
I = 2 SLEEP 1 S end
i = 1 thread = pool-1 -thread-2
total number of threads: 2 current number of active threads: 2
total number of threads: 2 current number of active threads: 2
I = end 1 sleep 1 s
total number of threads: 1 current number of active threads: 1
total number of threads: a current number of active threads: 1
I = 0 S SLEEP end. 3
total number of threads: a current number of active threads: 0
after the non-core can be seen that the number of threads is finished, the task into the queue continue to implement, such as re-enter the queue after the end of the task, you can see the total number of threads reduced 1, while the other core thread is finished, found that the total number of threads has not decreased, but reducing the number of active threads, which is the core number of threads is not recovered . Book says is correct, most of the online blog says keepAliveTime = 0 recovery is not permanent discrepancies.

If you want to set the recovery kernel threads, you need to set

executor.allowCoreThreadTimeOut (true);
but it is keepAliveTime must be> 0 for the job, otherwise it will throw an exception! ! !

throw new IllegalArgumentException ( "Core threads must have nonzero keep alive times");
If after watching have a problem, I hope you pointing something! ! Thank you! !
----------------
Disclaimer: This article is the original article CSDN bloggers "xuhangsong", and follow CC 4.0 BY-SA copyright agreement, reproduced, please attach the original source link and this statement. .
Original link: https: //blog.csdn.net/xuhangsong/article/details/89474989

Published 18 original articles · won praise 588 · Views 1.03 million +

Guess you like

Origin blog.csdn.net/hellozhxy/article/details/104503713