zoukankan      html  css  js  c++  java
  • keepAliveTime为0以及队列太小导致ThreadPoolExecutor不断创建新线程

    本文产生原因

    群友问题:

    使用ThreadPoolExecutor实现固定大小的线程池,但是程序跑一段时间后,就会重新创建新的线程,求问有人遇到过这个问题吗?
    在这里插入图片描述

    询问工作队列,最大线程数,超时时间参数值设置

    在这里插入图片描述

    猜测

    队列太小。容易导致队列满后,启动非核心线程。怀疑 keepAliveTime为0,导致线程池的线程runWorker期间,调用getTask不等待。

    线程池
    new ThreadPoolExecutor(corePoolSize, maximumPoolSize, keepAliveTime, timeUnit, workQueue,Executors.defaultThreadFactory(), defaultHandler);
    execute提交任务时:
    当execute时,线程小于corePoolSize,则addWorker(firstTask,true)创建新线程。
    当线程数量 大于核心数量corePoolSize后,则将任务入队。
    当workQueue到达最大数量时,继续创建线程直到线程数量大于maximumPoolSize
    当线程数量大于maximumPoolSize后,执行拒绝策略defaultHandler
    TERMINALTED:当非core线程空闲时间(getTask)超过keepAliveTime, timeUnit指定的时间后,则退出。
    threadPoolExecutor允许核心线程退出,类似于5.
    线程池中的线程何时死亡?

    源码

    查看源码,【keepAliveTime为0,会在队列为空的时候不等待】,返回0.(这里是ArrayBlockingQueue的实现)

    在这里插入图片描述
    在这里插入图片描述

    测试

    在这里插入图片描述

    jvisualVM 查看线程

    现象:能看见在不断创建线程。应该有一个核心线程,但所有线程的name都在变化。

    在这里插入图片描述

    结论:

    1. keepAliveTime为0以及队列太小导致ThreadPoolExecutor不断创建新线程
    2. 核心线程并不指的最先创建的那几个。 而是指当前少于core线程就算核心线程。
    3. keepAliveTime为0导致非core线程运行完后就休眠。查看ThreadPoolExecutor#getTask

    线程池中的线程何时死亡?

  • 相关阅读:
    2017.4.18下午
    2017.4.18上午
    2017.4.17上午
    2017.4.14下午
    2017.4.14上午
    4.17下午
    4.17上午
    4.13下午
    4.13上午
    4.10上午
  • 原文地址:https://www.cnblogs.com/thewindkee/p/12873120.html
Copyright © 2011-2022 走看看