代码示例:
public static void main(String[] args) { //创建线程池 ThreadPoolExecutor threadPoolExecutor = new ThreadPoolExecutor(10, 10, 1L, TimeUnit.SECONDS, new LinkedBlockingQueue<>(1), new ThreadPoolExecutor.AbortPolicy()); //设置核心线程空闲超时时关闭,默认为false threadPoolExecutor.allowCoreThreadTimeOut(true); MonitorThread monitorThread = new MonitorThread(); threadPoolExecutor.execute(monitorThread); LOG.info("线程池中线程数目:{},队列中等待执行的任务数目:{},已执行完的任务数目:{}", cutExecutor.getPoolSize(), cutExecutor.getQueue().size(), cutExecutor.getCompletedTaskCount()); }
一、创建线程池
1.ThreadPoolExecutor提供了四个构造方法
2.参数含义注意:
“keepAliveTime”该参数默认对核心线程无效,如果想应用到核心线程,则需要打开配置:threadPoolExecutor.allowCoreThreadTimeOut(true);
二、线程池触发拒绝策略
和数据源连接池不一样,线程池除了初始大小和池子最大值,还多了一个阻塞队列来缓冲。
数据源连接池一般请求的连接数超过连接池的最大值的时候就会触发拒绝策略,策略一般是阻塞等待设置的时间或者直接抛异常。
而线程池的触发时机如下图:
如图,想要了解线程池什么时候触发拒绝粗略,需要明确上面三个参数的具体含义,是这三个参数总体协调的结果,而不是简单的超过最大线程数就会触发线程拒绝粗略,
当提交的任务数大于corePoolSize时,会优先放到队列缓冲区,只有填满了缓冲区后,才会判断当前运行的任务是否大于maxPoolSize,小于时会新建线程处理,大于时就触发了拒绝策略。
总结就是:当前提交任务数大于(maxPoolSize + queueCapacity)时就会触发线程池的拒绝策略了。
参考: 1.线程池之ThreadPoolExecutor使用 2.ThreadPoolExecutor八种拒绝策略浅析