按照JDK文档的描述,

  • 如果池中的实际线程数小于corePoolSize,无论是否其中有空闲的线程,都会给新的任务产生新的线程
  • 如果池中的线程数>corePoolSize and <maximumPoolSize,而又有空闲线程,就给新任务使用空闲线程,如没有空闲线程,则产生新线程
  • 如果池中的线程数=maximumPoolSize,则有空闲线程使用空闲线程,否则新任务放入workQueue。(线程的空闲只有在workQueue中不再有任务时才成立)

ThreadPoolExecutor中有方法setCorePoolSize()和setMaximumPoolSize来设置corePoolSize和maximumPoolSize的大小,

  • 如果新值大于旧值,则对新任务新线程
  • 如果新值小于旧值,则在有线程空闲时,减少池中的线程数

但是在实际应用中想实时修改池的线程数,得有一定的条件,特别是要减少线程数,

  • 首先,如果提交的新任务太多,以至总是没有线程空闲下来,线程就不会减少
  • 即使有线程空闲,也不一定能减少线程,这还同所使用的workQueue有关,还需要workQueue.remainingCapacity==0。在JDK所提供的所有BlockingQueue中,只有SynchronousQueue的remainingCapacity()能返回0。

而如果实际应用中需要使用ScheduledThreadPoolExecutor来安排任务,同时需要新安排的任务数又非常多,这时要即时动态线程池的大小,就几乎不可能了,因为ScheduledThreadPoolExecutor用的是LinkedBlockingQueue。这时可以按照JDK的方式实现一个自己的ScheduledThreadPoolExecutor,

首先,稍微修改一下JDK的ThreadPoolExecutor就能实现一个自己的ThreadPoolExecutor,

  • 在setCorePoolSize方法中,去掉workQueue.remainingCapacity==0的条件
  • 让ThreadPoolExecutor中的Worker的interruptIfIdle()方法给Worker设置一个标志,让这个Worker不再检查workQueue中还没有执行的任务,立即中止
  • 还有就是修改一下ThreadPoolExecutor中实现的RejectedExecutionHandler,毕竟很多情况下都可以不需要它

有了自己ThreadPoolExecutor,就可以继承它来实现自己的ScheduledThreadPoolExecutor了(再原本照抄JDK的ScheduledThreadPoolExecutor的实现就可以了^_^)。

终于有了符合自己需要的ScheduledThreadPoolExecutor了,现在用它来每秒运行1000个任务,还需要每个小时改变并发任务数(50~200之间的随机值),至少要维持30天。

ThreadPoolExecutor的corePoolSize和maximumPoolSize的更多相关文章

  1. ThreadPoolExecutor 入参 corePoolSize 和 maximumPoolSize 的联系

    前言 我们可以通过 java.util.concurrent.ThreadPoolExecutor 来创建一个线程池: new ThreadPoolExecutor(corePoolSize, max ...

  2. 理解ThreadPoolExecutor线程池的corePoolSize、maximumPoolSize和poolSize

    我们知道,受限于硬件.内存和性能,我们不可能无限制的创建任意数量的线程,因为每一台机器允许的最大线程是一个有界值.也就是说ThreadPoolExecutor管理的线程数量是有界的.线程池就是用这些有 ...

  3. 线程池的corePoolSize、maximumPoolSize和poolSize

    什么是线程池: 为了避免系统频繁的创建和销毁线程,我们可以将创建的线程进行复用.在线程池中总有那么几个活跃的线程,也有一定的最大值限制,一个业务使用完线程之后,不是立即销毁而是将其放入到线程池中,从而 ...

  4. Android线程管理之ThreadPoolExecutor自定义线程池

    前言: 上篇主要介绍了使用线程池的好处以及ExecutorService接口,然后学习了通过Executors工厂类生成满足不同需求的简单线程池,但是有时候我们需要相对复杂的线程池的时候就需要我们自己 ...

  5. ThreadPoolExecutor源码学习(1)-- 主要思路

    ThreadPoolExecutor是JDK自带的并发包对于线程池的实现,从JDK1.5开始,直至我所阅读的1.6与1.7的并发包代码,从代码注释上看,均出自Doug Lea之手,从代码上看JDK1. ...

  6. 【JUC】JDK1.8源码分析之ThreadPoolExecutor(一)

    一.前言 JUC这部分还有线程池这一块没有分析,需要抓紧时间分析,下面开始ThreadPoolExecutor,其是线程池的基础,分析完了这个类会简化之后的分析,线程池可以解决两个不同问题:由于减少了 ...

  7. java线程池ThreadPoolExecutor使用简介

    一.简介线程池类为 java.util.concurrent.ThreadPoolExecutor,常用构造方法为:ThreadPoolExecutor(int corePoolSize, int m ...

  8. 线程池ThreadPoolExecutor、Executors参数详解与源代码分析

    欢迎探讨,如有错误敬请指正 如需转载,请注明出处 http://www.cnblogs.com/nullzx/ 1. ThreadPoolExecutor数据成员 Private final Atom ...

  9. ThreadPoolExecutor机制

    一.概述 1.ThreadPoolExecutor作为java.util.concurrent包对外提供基础实现,以内部线程池的形式对外提供管理任务执行,线程调度,线程池管理等等服务: 2.Execu ...

随机推荐

  1. HttpClient技术

    1.什么是HttpClient? 2.HttpClient特点? 特点: 2.1. 基于标准.纯净的Java语言.实现了Http1.0和Http1.1 2.2. 以可扩展的面向对象的结构实现了Http ...

  2. hive学习6

    将查询结果集写入另一个表中的时候报了这个错,Dynamic partition strict mode requires at least one static partition column. T ...

  3. SpringMVC中使用ModelAndView遇到的问题

    本文记录我在SpringMVC中使用ModelAndView,添加模型数据到ModelAndView中时遇到的问题: 1.jsp页面用EL表达式来获取值时直接显示EL表达式,JSP不解析EL表达式: ...

  4. pandas read_sql与read_sql_table、read_sql_query 的区别

    一:创建链接数据库引擎 from sqlalchemy import create_engine db_info = {'user':'user', 'password':'pwd', 'host': ...

  5. JVM内存管理基础概念

    .内存的不同形态 物理内存 虚拟内存 .内存的使用形式 内核空间 用户空间 .java虚拟机运行时数据划分 PC寄存器:保存当前程序运行时的内存地址. Java栈:总是和线程关联,每个线程拥有一个ja ...

  6. js字符串转dom

    function parse2dom(str){ var div = document.createElement("div"); if(typeof str == "s ...

  7. 如何学习Android系统源码(转)

    一. Android系统的源代码非常庞大和复杂,我们不能贸然进入,否则很容易在里面迷入方向,进而失去研究它的信心.我们应该在分析它的源代码之前学习好一些理论知识,下面就介绍一些与Android系统相关 ...

  8. VSCode使用正则表达式进行内容替换

    首先描述一下我要达到的目的: 1.源数据: 2.目标数据: 3.使用的正则表达式如下: (id: (\d+),) id: $2, \n order: $2,

  9. 解决Opencv高低版本不兼容问题

    目前OpenCV版本已更新到2.4...由此出现了一系列问题,解决如下: 1.cxcore.h等头文件找不到: 法一.将opencv1.0中的各种.h或者.lib文件拷到opencv2.3.1对应in ...

  10. tf.random_normal()函数

    tf.random_normal()函数用于从服从指定正太分布的数值中取出指定个数的值. tf.random_normal(shape, mean=0.0, stddev=1.0, dtype=tf. ...