线程池任务增长过程分析

 

    //线程缓冲队列
    private static BlockingQueue<Runnable> bqueue = new ArrayBlockingQueue<Runnable>(10);
    // 核心线程数
    private static final int SIZE_CORE_POOL = 5;
    // 线程池维护线程的最大数量
    private static final int SIZE_MAX_POOL = 9;
    // 线程池维护线程所允许的空闲时间
    private static final long ALIVE_TIME = 2000;
    //创建线程池
    private static ThreadPoolExecutor pool = new ThreadPoolExecutor(SIZE_CORE_POOL, SIZE_MAX_POOL, ALIVE_TIME, TimeUnit.MILLISECONDS, bqueue, new ThreadPoolExecutor.CallerRunsPolicy());
    static {
        //这个方法一调用,会让线程池立即初始化核心线程数相等数量的线程,如果不调用,初始线程数就是0,当有任务来的时候才会创建线程
        pool.prestartAllCoreThreads();
    }

 ThreadPoolExecutor构造函数的参数意义不再多说,按照上面的参数配置,说明一下执行20个任务且每个任务执行时间1秒,线程池中的线程和队列变化过程:
由于调用了prestartAllCoreThreads这个方法,线程池初始线程5个,添加前五个任务会分别占用一个线程执行,第六个任务开始会被放到bqueue队列中,队列长度是10所以到第15个任务的时候核心线程被占用,队列也满了,第16个任务就会创建新的线程执行,这些任务不经过队列排队所以会在队列中任务之前执行,直到第19个任务线程数达到SIZE_MAX_POOL大小数量9,不再创建线程,第20个任务就会按照阻塞策略执行,CallerRunsPolicy这个策略的意思就是在调用者线程中直接执行任务,也是不经过排队,效果和前面创建线程执行一样,随着任务被执行,队列中的任务被消费掉队列的长度也会恢复到0,空闲线程空闲时间超过2秒线程会关闭,最后保留5个线程存活,用一个main方法进行验证:

public static void main(String[] args) throws InterruptedException {
        for (int i = 1; i <= 20; i++) {
            System.out.println("线程池线程数:" + pool.getPoolSize() + ",队列长度" + pool.getQueue().size());
            System.out.println("调用第" + i + "个任务");
            final int a = i;
            pool.execute(new Runnable() {

                @Override
                public void run() {
                    try {
                        Thread.sleep(1000);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                    System.out.println("完成第" + a + "个任务");
                }
            });
        }
        System.out.println("任务调用完成");
        for (int i = 0; i < Integer.MAX_VALUE; i++) {
            Thread.sleep(1000);
            System.out.println("线程池线程数:" + pool.getPoolSize() + ",队列长度" + pool.getQueue().size());
        }
    }

执行结果:

线程池线程数:5,队列长度0
调用第1个任务
线程池线程数:5,队列长度1
调用第2个任务
线程池线程数:5,队列长度1
调用第3个任务
线程池线程数:5,队列长度1
调用第4个任务
线程池线程数:5,队列长度0
调用第5个任务
线程池线程数:5,队列长度1
调用第6个任务
线程池线程数:5,队列长度1
调用第7个任务
线程池线程数:5,队列长度2
调用第8个任务
线程池线程数:5,队列长度3
调用第9个任务
线程池线程数:5,队列长度4
调用第10个任务
线程池线程数:5,队列长度5
调用第11个任务
线程池线程数:5,队列长度6
调用第12个任务
线程池线程数:5,队列长度7
调用第13个任务
线程池线程数:5,队列长度8
调用第14个任务
线程池线程数:5,队列长度9
调用第15个任务
线程池线程数:5,队列长度10
调用第16个任务
线程池线程数:6,队列长度10
调用第17个任务
线程池线程数:7,队列长度10
调用第18个任务
线程池线程数:8,队列长度10
调用第19个任务
线程池线程数:9,队列长度10
调用第20个任务
完成第4个任务
完成第5个任务
完成第17个任务
完成第18个任务
完成第2个任务
完成第1个任务
完成第20个任务
完成第16个任务
完成第3个任务
任务调用完成
完成第19个任务
完成第6个任务
完成第12个任务
完成第9个任务
完成第14个任务
线程池线程数:9,队列长度0
完成第8个任务
完成第10个任务
完成第11个任务
完成第7个任务
完成第13个任务
完成第15个任务
线程池线程数:9,队列长度0
线程池线程数:9,队列长度0
线程池线程数:5,队列长度0
线程池线程数:5,队列长度0
线程池线程数:5,队列长度0
线程池线程数:5,队列长度0

注释掉静态代码块中的pool.prestartAllCoreThreads();再执行线程数会从0开始,线程会在有任务执行的时候再去创建:

线程池线程数:0,队列长度0
调用第1个任务
线程池线程数:1,队列长度0
调用第2个任务
线程池线程数:2,队列长度0
调用第3个任务
线程池线程数:3,队列长度0
调用第4个任务
线程池线程数:4,队列长度0
调用第5个任务
线程池线程数:5,队列长度0
调用第6个任务
线程池线程数:5,队列长度1
调用第7个任务
线程池线程数:5,队列长度2
调用第8个任务
线程池线程数:5,队列长度3
调用第9个任务
线程池线程数:5,队列长度4
调用第10个任务
线程池线程数:5,队列长度5
调用第11个任务
线程池线程数:5,队列长度6
调用第12个任务
线程池线程数:5,队列长度7
调用第13个任务
线程池线程数:5,队列长度8
调用第14个任务
线程池线程数:5,队列长度9
调用第15个任务
线程池线程数:5,队列长度10
调用第16个任务
线程池线程数:6,队列长度10
调用第17个任务
线程池线程数:7,队列长度10
调用第18个任务
线程池线程数:8,队列长度10
调用第19个任务
线程池线程数:9,队列长度10
调用第20个任务
完成第1个任务
完成第2个任务
完成第3个任务
完成第4个任务
完成第5个任务
完成第18个任务
完成第19个任务
完成第20个任务
完成第17个任务
完成第16个任务
任务调用完成
完成第6个任务
完成第7个任务
完成第10个任务
完成第9个任务
完成第8个任务
线程池线程数:9,队列长度0
完成第13个任务
完成第12个任务
完成第14个任务
完成第11个任务
完成第15个任务
线程池线程数:9,队列长度0
线程池线程数:5,队列长度0
线程池线程数:5,队列长度0
线程池线程数:5,队列长度0
线程池线程数:5,队列长度0

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值