当前位置: 首页 > news >正文

ThreadPoolExecutor运转机制详解

最近发现几起对ThreadPoolExecutor的误用,其中包括自己,发现都是因为没有仔细看注释和内部运转机制,想当然的揣测参数导致,先看一下新建一个ThreadPoolExecutor的构建参数:

public ThreadPoolExecutor(int corePoolSize, int maximumPoolSize, long keepAliveTime, TimeUnit unit, BlockingQueue<Runnable> workQueue, ThreadFactory threadFactory, RejectedExecutionHandler handler)

看这个参数很容易让人以为是线程池里保持corePoolSize个线程,如果不够用,就加线程入池直至maximumPoolSize大小,如果还不够就往workQueue里加,如果workQueue也不够就用RejectedExecutionHandler来做拒绝处理。

但实际情况不是这样,具体流程如下:

1)当池子大小小于corePoolSize就新建线程,并处理请求

2)当池子大小等于corePoolSize,把请求放入workQueue中,池子里的空闲线程就去从workQueue中取任务并处理

3)当workQueue放不下新入的任务时,新建线程入池,并处理请求,如果池子大小撑到了maximumPoolSize就用RejectedExecutionHandler来做拒绝处理

4)另外,当池子的线程数大于corePoolSize的时候,多余的线程会等待keepAliveTime长的时间,如果无请求可处理就自行销毁

内部结构如下所示:

从中可以发现ThreadPoolExecutor就是依靠BlockingQueue的阻塞机制来维持线程池,当池子里的线程无事可干的时候就通过workQueue.take()阻塞住。

其实可以通过Executes来学学几种特殊的ThreadPoolExecutor是如何构建的。

public static ExecutorService newFixedThreadPool(int nThreads) { return new ThreadPoolExecutor(nThreads, nThreads, 0L, TimeUnit.MILLISECONDS, new LinkedBlockingQueue<Runnable>()); }

newFixedThreadPool就是一个固定大小的ThreadPool

public static ExecutorService newCachedThreadPool() { return new ThreadPoolExecutor(0, Integer.MAX_VALUE, 60L, TimeUnit.SECONDS, new SynchronousQueue<Runnable>()); }

newCachedThreadPool比较适合没有固定大小并且比较快速就能完成的小任务,没必要维持一个Pool,这比直接new Thread来处理的好处是能在60秒内重用已创建的线程。

其他类型的ThreadPool看看构建参数再结合上面所说的特性就大致知道它的特性

相关文章:

  • 图片垂直居中在中间
  • MeeGo handset 1.1开发环境[5]:一个desktop小应用
  • Java虚拟机学习 - 对象访问
  • 20款Notepad++插件下载和介绍
  • ios协议
  • UIComponent的生命周期(life cycle)
  • spring(一)IOC AOP
  • 深入分析Flex [Bindable] 以及使用方法
  • indy10 学习2
  • 一个网页设计需求方眼中的网页设计
  • 正则表达式入门以及记录
  • 谈谈网页设计师的成长之路
  • 07.常用的SQL语句
  • 初步接触html心得
  • AS3所有类的接口实现一览表
  • 【划重点】MySQL技术内幕:InnoDB存储引擎
  • 10个最佳ES6特性 ES7与ES8的特性
  • C++11: atomic 头文件
  • CSS 三角实现
  • CSS实用技巧干货
  • HashMap ConcurrentHashMap
  • HashMap剖析之内部结构
  • Javascript设计模式学习之Observer(观察者)模式
  • JS+CSS实现数字滚动
  • js学习笔记
  • Spring技术内幕笔记(2):Spring MVC 与 Web
  • unity如何实现一个固定宽度的orthagraphic相机
  • vue的全局变量和全局拦截请求器
  • 跨域
  • 面试题:给你个id,去拿到name,多叉树遍历
  • 算法之不定期更新(一)(2018-04-12)
  • 我这样减少了26.5M Java内存!
  • 一个普通的 5 年iOS开发者的自我总结,以及5年开发经历和感想!
  • 阿里云ACE认证之理解CDN技术
  • ​​​​​​​​​​​​​​汽车网络信息安全分析方法论
  • ​总结MySQL 的一些知识点:MySQL 选择数据库​
  • # 达梦数据库知识点
  • # 透过事物看本质的能力怎么培养?
  • #NOIP 2014#Day.2 T3 解方程
  • #我与Java虚拟机的故事#连载16:打开Java世界大门的钥匙
  • (17)Hive ——MR任务的map与reduce个数由什么决定?
  • (C语言)strcpy与strcpy详解,与模拟实现
  • (java)关于Thread的挂起和恢复
  • (第二周)效能测试
  • (分享)自己整理的一些简单awk实用语句
  • (附源码)ssm户外用品商城 毕业设计 112346
  • (每日持续更新)信息系统项目管理(第四版)(高级项目管理)考试重点整理第3章 信息系统治理(一)
  • (推荐)叮当——中文语音对话机器人
  • (万字长文)Spring的核心知识尽揽其中
  • (原創) 如何使用ISO C++讀寫BMP圖檔? (C/C++) (Image Processing)
  • (正则)提取页面里的img标签
  • (转)大道至简,职场上做人做事做管理
  • (转)用.Net的File控件上传文件的解决方案
  • .chm格式文件如何阅读
  • .net core 调用c dll_用C++生成一个简单的DLL文件VS2008