美文网首页
java ThreadPoolExecutor踩坑记

java ThreadPoolExecutor踩坑记

作者: Ronry | 来源:发表于2017-08-22 21:51 被阅读0次

首先简单介绍下ThreadPoolExecutor的原理,如图:


image.png

每当有新任务需要提交到线程池执行的时候,大概的过程如下:

  • step1.调用ThreadPoolExecutor的execute提交线程,首先检查CorePool,如果CorePool内的线程小于CorePoolSize,新创建线程执行任务。
  • step2.如果当前CorePool内的线程大于等于CorePoolSize,那么将任务加入到BlockingQueue。
  • step3.如果不能加入BlockingQueue,在小于MaxPoolSize的情况下创建线程执行任务。
  • step4.如果线程数大于等于MaxPoolSize,那么执行拒绝策略。

其中1,2,4步骤的机制原来也就知道,只是对于step3原先关注的不多,这次踩到了。本意是想让超出MaxPoolSize的时候,任务能执行在父线程里执行,所以想当然的将BlockingQueue的大小设置为1了。结果出现的现象是,在并发很低的情况下,出现了任务被线程池拒绝的情况。调试了一下午,才发现卡在了step3,源代码如下:

       int c = ctl.get();
        if (workerCountOf(c) < corePoolSize) {
            if (addWorker(command, true))
                return;
            c = ctl.get();
        } 
       // step 3 workQueue.offer(command))
        if (isRunning(c) && workQueue.offer(command)) {
            int recheck = ctl.get();
            if (! isRunning(recheck) && remove(command))
                reject(command);
            else if (workerCountOf(recheck) == 0)
                addWorker(null, false);
        }
        else if (!addWorker(command, false))
            reject(command);

关键点就在workQueue.offer(command))这句:如果当前线程数已经大于coreSize了,则会先尝试往对列里放。如果队列已经满了,则直接看能不能再建线程,如果还不能则走拒绝策略。这个时候,其实coreSize的线程可能都是空闲的,他们是在等待workQueue里有新的任务出现。而新的任务(特别是一次性批量提交大于1个的时候),因为BlockingQueue size是1,所以只有1个能提交成功,其他的都被拒绝了。
想想也是啊,这就是一个生产者消费者模式,线程被创建出来之后,和后续提交的任务之间唯一媒介就是workQueue!!

更详细的关于ThreadPoolExecutor的机制可以参考:
http://www.jianshu.com/p/ade771d2c9c0

相关文章

  • java ThreadPoolExecutor踩坑记

    首先简单介绍下ThreadPoolExecutor的原理,如图: 每当有新任务需要提交到线程池执行的时候,大概的过...

  • JAVA踩坑记

    1.String 相等 稍微有点经验的程序员都会用equals比较而不是用 ==,但用equals就真的安全了吗,...

  • Java 线程池详解

    Java ThreadPoolExecutor详解 ThreadPoolExecutor是Java语言对于线程池的...

  • Executor框架使用ThreadPoolExecutor

    java线程池 - ThreadPoolExecutor ThreadPoolExecutor是Executor框...

  • Android Material Design 踩坑记(2)

    Android Material Design 踩坑记(1) CoordinatorLayout Behav...

  • java线程池

    1.Java中的ThreadPoolExecutor类 1)Java中的ThreadPoolExecutor类是线...

  • ThreadPoolExecutor使用详解

    ThreadPoolExecutor机制 一、概述 ThreadPoolExecutor作为java.util.c...

  • ThreadPoolExecutor机制

    ThreadPoolExecutor机制 一、概述 ThreadPoolExecutor作为java.util.c...

  • Java AOP 实例踩坑记

    其实这篇文章是存了很久的草稿,写了一半没有继续完稿。终于得空继续完善它,之后还会抽时间继续研究Spring AOP...

  • Java守护线程踩坑记

    笔者最近在排查一次线上故障时, 发现一个很奇怪的现象: 线上服务启动时,没有任何流量和访问,服务cpu使用率莫名妙...

网友评论

      本文标题:java ThreadPoolExecutor踩坑记

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