【并发编程】- ThreadPoolExecutor 核心线程数与实际任务关系

114 阅读2分钟

持续创作,加速成长!这是我参与「掘金日新计划 · 6 月更文挑战」的第9天,点击查看活动详情

在使用线程池中会出现如下5种情况:

简化部分参数

A:execute(runnable)想执行的runnable的数量。

B:corePoolSize核心线程数

C:maximumPoolSize最大线程数

D:A-B(A>=B)

E:new LinkedBlockingDeque() 队列,无构造参数

F:SynchronousQueue队列

G:keepAliveTime

  1. A<=B,立即创建线程运行这个任务,并不放入扩展队列Queue中。
  2. A>B&&A<=C&&E,则C和G参数忽略,并把D放入E中等待被执行。
  3. A>B&&A<=C&&F,则C和G参数有效,并且马上创建线程运行这些任务,而不把D放入F中,D执行完任务后在指定时间后发生超时时将D进行清除。
  4. A>B&&A>C&&E,则C和G参数忽略,并把D放入E中等待被执行。
  5. A>B&&A>C&&F,则处理C的任务,其他任务则不再处理抛出异常。

在线程池中添加的线程数量大于等于corePoolSize

线程池使用了LinkedBlockingDeque,并且线程数量小于等于corePoolSize,所以KeepAliveTime>5时也不会清除空闲数据。

实现代码如下:

public class CorePoolSizeRun {
    public static void main(String[] args) {
        Runnable runnable = new Runnable() {
            @Override
            public void run() {
                System.out.println(Thread.currentThread().getName()+" 在执行时间: "+System.currentTimeMillis());
                try {
                    Thread.sleep(1000);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        };

        ThreadPoolExecutor threadPoolExecutor = new ThreadPoolExecutor(5, 6, 5, TimeUnit.SECONDS, new LinkedBlockingDeque<Runnable>());
        for (int i = 0; i < 5; i++) {
            threadPoolExecutor.execute(runnable);
        }
        try {
            Thread.sleep(100);
            System.out.println("第一阶段线程池核心线程数:"+threadPoolExecutor.getCorePoolSize());
            System.out.println("第一阶段线程池实际线程数:"+threadPoolExecutor.getPoolSize());
            System.out.println("第一阶段线程池队列数:"+threadPoolExecutor.getQueue().size());
            Thread.sleep(10000);
            System.out.println("第二阶段线程池核心线程数:"+threadPoolExecutor.getCorePoolSize());
            System.out.println("第二阶段线程池实际线程数:"+threadPoolExecutor.getPoolSize());
            System.out.println("第二阶段线程池队列数:"+threadPoolExecutor.getQueue().size());
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }
}

运行结果如下:

pool-1-thread-1 在执行时间: 1654068981090
pool-1-thread-4 在执行时间: 1654068981091
pool-1-thread-2 在执行时间: 1654068981090
pool-1-thread-3 在执行时间: 1654068981090
pool-1-thread-5 在执行时间: 1654068981091
第一阶段线程池核心线程数:5
第一阶段线程池实际线程数:5
第一阶段线程池队列数:0
第二阶段线程池核心线程数:5
第二阶段线程池实际线程数:5
第二阶段线程池队列数:0

从运行结果看出由于线程数量小于等于最大线程数,说明corePool核心池中的线程超过5秒钟不会被清除,5个线程对象成功被创建运行了,说明线程池核心线程数在运行,符合5种情况中第一种情况。