按照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. Nginx错误日志配置信息详解

    Nginx的错误日志可以配置在Main区块,也可以配置在虚拟主机区块中.Nginx软件会把自身运行的故障信息及用户访问的日志信息记录到指定的日志文件里,是我们调试Nginx服务的重要参考. error ...

  2. 30道linux运维面试题(很精典)

    https://zhangge.net/1986.html 1.linux 如何挂在 windows 下的共享目录         Shell   1 mount.cifs //192.168.1.3 ...

  3. VC SOCKET 压缩通信学习

    Server................// Server.cpp : Defines the entry point for the console application. // #inclu ...

  4. 简学Python第五章__模块介绍,常用内置模块

    Python第五章__模块介绍,常用内置模块 欢迎加入Linux_Python学习群  群号:478616847 目录: 模块与导入介绍 包的介绍 time &datetime模块 rando ...

  5. waitpid使用的一点问题

    使用waipid的时候遇到了一个奇怪的问题,将情况简化后描述一下. 有关waitpid的基本介绍参见这里一下:http://www.cnblogs.com/mickole/p/3187770.html ...

  6. Python之flask总结

    一.flask      a.Flask是一个基于Python开发并且依赖jinja2模板和Werkzeug WSGI服务的一个微型框架,对于Werkzeug本质是Socket服务端,其用于接收htt ...

  7. 论文笔记 — MatchNet: Unifying Feature and Metric Learning for Patch-Based Matching

    论文:https://github.com/ei1994/my_reference_library/tree/master/papers 本文的贡献点如下: 1. 提出了一个新的利用深度网络架构基于p ...

  8. hdu 5241 Friends(找规律?)

    Friends Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 262144/262144 K (Java/Others)Total S ...

  9. hdu 1846 Brave Game(bash)

    Brave Game Time Limit: 1000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total ...

  10. 使用ES6的Promise 解决回调函数。

    //创建一个Promise实例,获取数据.并把数据传递给处理函数resolve和reject.需要注意的是Promise在声明的时候就执行了. var getUserInfo=new Promise( ...