java ThreadPoolExecutor 线程池构造方法参数:keepAliveTime最大时间

说明

默认情况下,如果空闲线程的存活时间,超过这个时间, 空闲线程被回收(但核心线程不会回收)

空闲线程

当线程的任务执行后,即:run() 方法里面的代码执行结束后,就是空闲线程

类比

学校规定,当教室没有人时,就是空闲教室,空闲超过1小时,就要关闭空调,否则就浪费电

该参数可能无意义

因为默认情况下,核心线程不会回收,所以:核心线程数量,等于 最大线程数量,那么这个参数无意义

例子

设置 线程池 核心线程数是 1,最大线程数是3,空闲线程最大存活时间 5s,阻塞队列长度 1

package ThreadPool;

import java.time.LocalTime;
import java.util.concurrent.LinkedBlockingQueue;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;

public class KeepAliveTime {
    public static void main(String[] args) {
        ThreadPoolExecutor threadPoolExecutor = new ThreadPoolExecutor(
                1,
                3,
                5,
                TimeUnit.SECONDS,
                new LinkedBlockingQueue(1)
        );
//        threadPoolExecutor.allowCoreThreadTimeOut(true);
        threadPoolExecutor.execute(new MyRun("1"));
        threadPoolExecutor.execute(new MyRun("2"));
        threadPoolExecutor.execute(new MyRun("3"));
        threadPoolExecutor.execute(new MyRun("4"));


        for(;;){
            print(threadPoolExecutor);
            try {
                Thread.sleep(1000);
            } catch (InterruptedException e) {
                throw new RuntimeException(e);
            }
        }
    }

    static void print(ThreadPoolExecutor threadPoolExecutor){
        LocalTime time = LocalTime.now();
        System.out.println("  "+time+",活动线程数:"+threadPoolExecutor.getActiveCount());
        System.out.println("  "+time+",线程池中的线程数:"+threadPoolExecutor.getPoolSize());
    }
    static class MyRun implements Runnable {
        String name;

        public MyRun(String name) {
            this.name = name;
        }

        @Override
        public void run() {
            System.out.println(name+"--开始");
            try {
//                for(int i =0;true;++i) {
//                    System.out.println(name+",i="+i);
//                    Thread.sleep(1000);
//                }
                Thread.sleep(2000);

            } catch (InterruptedException e) {
                throw new RuntimeException(e);
            }
            System.out.println(name+"--结束");
        }
    }
}

执行结果:

执行步骤:

  • 首先提交 任务1 ,立即创建线程 ,执行任务1;
  • 提交 任务2 时,任务1还未完成,于是,将任务2,保存到 阻塞队列中
  • 提交 任务3 ,此时 任务1 未完成,任务2 还在阻塞队列中等待,所以此时已经达到核心线程数,并且阻塞队列已经满了,但还没有达到最大线程数,因此,创建新线程执行任务3
  • 任务4 提交,此时 任务1 未完成,任务2 还在阻塞队列中等待,任务3 也未完成,所以此时已经达到核心线程数,并且阻塞队列已经满了,但还没有达到最大线程数,因此,创建新线程执行任务4
  • 此时 活动线程数是 3,线程池中的线程数:3
  • 任务 1 执行完毕,队列中的任务 2开始执行。此时线程数还是 3

  • 任务 3、任务4 相继执行完毕,因为 空闲线程最大存活时间 5s ,所以,线程池中的线程不会回收。活动线程数:1(任务 2在运行),线程池中的线程数:3

  • 任务 3结束的 5s 后,线程池开始回收空闲线程,所以,活动线程数:0(任务 2 此时也执行完毕),线程池中的线程数:1,因为核心线程数是1,默认核心线程不会超时终止。

例子2

调用下面方法,可以回收核心线程

.allowCoreThreadTimeOut(true);

代码:

package ThreadPool;

import java.time.LocalTime;
import java.util.concurrent.LinkedBlockingQueue;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;

public class KeepAliveTime {
    public static void main(String[] args) {
        ThreadPoolExecutor threadPoolExecutor = new ThreadPoolExecutor(
                1,
                3,
                5,
                TimeUnit.SECONDS,
                new LinkedBlockingQueue(1)
        );
        threadPoolExecutor.allowCoreThreadTimeOut(true);
        threadPoolExecutor.execute(new MyRun(1));
        threadPoolExecutor.execute(new MyRun(2));
        threadPoolExecutor.execute(new MyRun(3));
        threadPoolExecutor.execute(new MyRun(4));


        for(;;){
            print(threadPoolExecutor);
            try {
                Thread.sleep(1000);
            } catch (InterruptedException e) {
                throw new RuntimeException(e);
            }
        }
    }

    static void print(ThreadPoolExecutor threadPoolExecutor){
        LocalTime time = LocalTime.now();
        System.out.println("  "+time+",活动线程数:"+threadPoolExecutor.getActiveCount());
        System.out.println("  "+time+",线程池中的线程数:"+threadPoolExecutor.getPoolSize());
    }
    static class MyRun implements Runnable {
        int index;

        public MyRun(int name) {
            this.index = name;
        }

        @Override
        public void run() {
            System.out.println(index +"--开始");
            try {
//                for(int i =0;true;++i) {
//                    System.out.println(name+",i="+i);
//                    Thread.sleep(1000);
//                }
                Thread.sleep(2000* index);

            } catch (InterruptedException e) {
                throw new RuntimeException(e);
            }
            System.out.println(index +"--结束");
        }
    }
}

执行最后结果:

线程池中的线程数:0 // 说明核心线程也回收了

参考:
https://blog.csdn.net/weixin_44730681/article/details/113791867


原文出处:/show_1IX4d4xOdc8e.html