美文网首页
Android java ThreadPoolExecutor

Android java ThreadPoolExecutor

作者: Bfmall | 来源:发表于2021-04-06 17:59 被阅读0次
    20200730114223412.png

    首先,由图可以看出:

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

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

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

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

    再来看看代码:

    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。
    ————————————————
    版权声明:本文为CSDN博主「bug猎手」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
    原文链接:https://blog.csdn.net/hanye2020/article/details/107686887

    相关文章

      网友评论

          本文标题:Android java ThreadPoolExecutor

          本文链接:https://www.haomeiwen.com/subject/dfhekltx.html