Android java ThreadPoolExecutor 线程池 一张图理解原理 执行流程 正确理解核心线程 非核心线程

在这里插入图片描述
首先,由图可以看出:

  1. execute一个线程时,线程池内数量 < corePoolSize时,直接启动一个核心线程执行任务;

  2. execute一个线程时,线程池内数量 >= corePoolSize,workQueue未满时,线程放入workQueue等待执行;

  3. execute一个线程时,线程池内数量 >= corePoolSize,workQueue已满,线程池内数量 < maximumPoolSize时,启动一个非核心线程执行任务;

  4. execute一个线程时,线程池内数量 >= corePoolSize,workQueue已满,线程池内数量 >= maximumPoolSize时,调用RejectedExecutionHandler抛出RejectedExecutionException;

再来看看代码:

    ThreadPoolExecutor executor;

    private void threadTest() {
        final String TAG = "ThreadPoolExecutor test";
        int corePoolSize = 5;
        int maximumPoolSize = 10;
        int workQueueSize = 100;

        if (executor == null) {
            executor = new ThreadPoolExecutor(corePoolSize, maximumPoolSize, 0,
                    TimeUnit.SECONDS, new LinkedBlockingQueue<Runnable>(workQueueSize));
        }

        for (int i = 0; i < 50; i++) {
            final int finalI = i;
            executor.execute(new Runnable() {
                @Override
                public void run() {
                    try {
                        Thread.sleep(2000);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                    Log.e(TAG, "thread name:" + Thread.currentThread().getName() + " index:" + finalI
                            + "  hashCode: " + Thread.currentThread().hashCode());
                }
            });
        }
    }

  1. 当corePoolSize = 5,workQueue Size = 100,maximumPoolSize = 10;
    for循环,execute 50个线程,
    前5个,创建核心线程执行任务,剩下50 - 5 = 45,因为workQueue Size = 100,未满,所以剩下45个将放入workQueue等待执行;

    运行结果:每2s执行5条线程,即打印5条Log;

  2. 改一下条件,当corePoolSize = 5,workQueue Size = 40,maximumPoolSize = 10;
    for循环,execute 50个线程,
    前5个,创建核心线程执行任务,剩下50 - 5 = 45,因为workQueue Size = 40,放入workQueue 40个,workQueue满了,剩下45 - 40 = 5个,这时,当前已经有核心线程5个,也就是当前线程池数量为5 < maximumPoolSize 10, 所以会开启5个非核心线程执行任务,这5个非核心线程也会执行workQueue的任务;

    运行结果:每2s执行10条线程,即打印10条Log;

  3. 再改一下条件,当corePoolSize = 5,workQueue Size = 40,maximumPoolSize = 10;
    for循环,execute 51个线程,
    前5个,创建核心线程执行任务,剩下51 - 5 = 46,因为workQueue Size = 40,放入workQueue 40个,workQueue满了,剩下46 - 40 = 6个,这时,当前已经有核心线程5个,也就是当前线程池数量为5 < maximumPoolSize 10, 所以会开启5个非核心线程执行任务,然后剩下6 - 5 = 1个,而此时线程池内数量已为10,剩下的1个超出了maximumPoolSize,所以会抛出RejectedExecutionException;

    运行结果:抛出RejectedExecutionException;

注意注意注意,以下很重要:
  1. 第1种情况时,因为corePoolSize = 5,workQueue未满,所以池里从始至终都是这5条线程作为核心线程;

  2. 第2种情况时,出现了非核心线程,也就是说线程总数大于corePoolSize,执行完任务后,池的大小会维护在corePoolSize的数量,不管原来是核心线程还是非核心线程,留在池内的就成为核心线程,多出的线程就会被回收销毁,所以池内的核心线程并不一定是原来的核心线程,也就是说,其实所有的线程都是一样的,没有特殊标明哪条是核心线程,哪条是非核心线程,最后幸存下来的就是核心线程!可以使用上边的代码打印日志观察hashCode。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值