线程池技术在并发时经常会使用到,java中的线程池的使用是通过调用ThreadPoolExecutor来实现的。ThreadPoolExecutor提供了四个构造函数,最后都会归结于下面这个构造方法:

// 七个参数的构造函数
public ThreadPoolExecutor(int corePoolSize,
int maximumPoolSize,
long keepAliveTime,
TimeUnit unit,
BlockingQueue<Runnable> workQueue,
ThreadFactory threadFactory,
RejectedExecutionHandler handler)

这些参数的意义如下:

  • corePoolSize:该线程池中核心线程数最大值
  • maximumPoolSize: 该线程池中线程总数最大值
  • keepAliveTime:该线程池中非核心线程闲置超时时长
  • unit:keepAliveTime的单位
  • workQueue:阻塞队列BlockingQueue,维护着等待执行的Runnable对象
  • threadFactory:创建线程的接口,需要实现他的Thread newThread(Runnable r)方法。
  • RejectedExecutionHandler:饱和策略,最大线程和工作队列容量且已经饱和时execute方法都将调用RejectedExecutionHandler 。

ThreadPoolExecutor工作流程

流程图如下:

大致过程陈述为:

  1. 向线程池中添加任务,当任务数量少于corePoolSize时,会自动创建thead来处理这些任务;

  2. 当添加任务数大于corePoolSize且少于maximmPoolSize时,不在创建线程,而是将这些任务放到阻塞队列中,等待被执行;

  3. 接上面2的条件,且当阻塞队列满了之后,继续创建thread,从而加速处理阻塞队列;

  4. 当添加任务大于maximmPoolSize时,根据饱和策略决定是否容许继续向线程池中添加任务,默认的饱和策略是AbortPolicy(直接丢弃)。

线程池中使用的阻塞队列

  • ArrayBlockingQueue:基于数组结构的有界阻塞队列,构造函数一定要传大小,FIFO(先进先出);

  • LinkedBlockingQueue:无界,默认大小65536(Integer.MAX_VALUE),当大量请求任务时,容易造成内存耗尽。

  • SynchronousQueue:同步队列,是一个特殊的BlockingQueue,它没有容量(这是因为在SynchronousQueue中,插入将等待另一个线程的删除操作,反之亦然)。具体可以参考:《Java SynchronousQueue Examples(译)》

  • PriorityBlockingQueue: 优先队列,无界。

  • DelayedWorkQueue:这个队列接收到任务时,首先先入队,只有达到了指定的延时时间,才会执行任务

阻塞队列常见的方法如下表所示:

方法名 说明 注意
add 增加一个元索 如果队列已满,则抛出一个IIIegaISlabEepeplian异常
remove 移除并返回队列头部的元素 如果队列为空,则抛出一个NoSuchElementException异常
element 返回队列头部的元素 如果队列为空,则抛出一个NoSuchElementException异常
offer 添加一个元素并返回true 如果队列已满,则返回false
poll 移除并返问队列头部的元素 如果队列为空,则返回null
peek 返回队列头部的元素 如果队列为空,则返回null
put 添加一个元素 如果队列满,则阻塞
take 移除并返回队列头部的元素 如果队列为空,则阻塞

常见四种线程池

  • newCachedThreadPool
  • newFixedThreadPool
  • newSingleThreadExecutor
  • newScheduledThreadPool
线程池 使用的阻塞队列 线程池大小 超时
CachedThreadPool SynchronousQueue(队列长度无限 可增加,最大值Integer.MAX_VALUE 默认60秒超时
FixedThreadPool LinkedBlockingQueue(队列长度无限) 可指定nThreads,固定数量 不会超时
newSingleThreadExecutor LinkedBlockingQueue(队列长度无限), 固定为1 不超时
newScheduledThreadPool DelayedWorkQueue 可增加,最大值Integer.MAX_VALUE 不超时

它们通过Executors以静态方法的方式直接调用,实质上是它们最终调用的是ThreadPoolExecutor的构造方法,也就是本文最前面那段代码。

注:KeepAliveTime=0的话,表示不等待

《阿里巴巴java开发手册》中建议线程池不使用 Executors 去创建,而是通过 ThreadPoolExecutor的方式,这样的处理方式让写的人员更加明确线程池的运行规则,规避资源耗尽的风险。

参考: 《线程池的状态及KeepAliveTime参数》

ThreadPoolExecutor常识的更多相关文章

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

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

  2. 读《乔布斯的NeXT和苹果之间,隔了这两个创业常识》

    原文链接:http://wwww.huxiu.com/article/114950/1.html 前言: 当今硅谷风头最劲的风险投资家马克·安德森曾说,硅谷每年大约诞生15-20家真正值得投资的公司. ...

  3. 并发包的线程池第一篇--ThreadPoolExecutor执行逻辑

    学习这个很长时间了一直没有去做个总结,现在大致总结一下并发包的线程池. 首先,任何代码都是解决问题的,线程池解决什么问题? 如果我们不用线程池,每次需要跑一个线程的时候自己new一个,会导致几个问题: ...

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

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

  5. ThreadPoolExecutor源码学习(2)-- 在thrift中的应用

    thrift作为一个从底到上除去业务逻辑代码,可以生成多种语言客户端以及服务器代码,涵盖了网络,IO,进程,线程管理的框架,着实庞大,不过它层次清晰,4层每层解决不同的问题,可以按需取用,相当方便. ...

  6. Java 线程 — ThreadPoolExecutor

    线程池 线程池处理流程 核心线程池:创建新线程执行任务,需要获取全局锁 队列:将新来的任务加入队列 线程池:大于corePoolSize,并且队列已满,小于maxPoolSize,创建新的worker ...

  7. java 线程池ThreadPoolExecutor 如何与 AsyncTask() 组合使用。

    转载请声明出处谢谢!http://www.cnblogs.com/linguanh/ 这里主要使用Executors中的4种静态创建线程池实例方法中的 newFixedThreadPool()来举例讲 ...

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

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

  9. java线程池ThreadPoolExecutor使用简介

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

随机推荐

  1. python selenium-2 定位元素

    元素 方法 示例 id find_element_by_id('su') driver.get("http://www.baidu.com")driver.find_element ...

  2. python3 钉钉群机器人 webhook

    import requests import json url='https://oapi.dingtalk.com/robot/send?access_token=替换成你自己的toten' pro ...

  3. 在ie6下的png图片的兼容问题

    png图片在ie6下是这样的: 正确样式: 这样解决: html代码: <body> <div class="gys"></div> </ ...

  4. mysql更新(四) 数据类型

    07-数据类型   介绍 存储引擎决定了表的类型,而表内存放的数据也要有不同的类型,每种数据类型都有自己的宽度,但宽度是可选的 详细参考链接:http://www.runoob.com/mysql/m ...

  5. async task 异步消息

     async 和 await 是用来定义的异步方法,async  关键字是上下文关键字,原因在于只有当它修饰方法.lambda 表达式或匿名方法时,它才是关键字. 在所有其他上下文中,都会将其解释为标 ...

  6. CYQ.Data 批量添加数据性能测试(每秒千、万)---003

    原文地址:https://www.cnblogs.com/cyq1162/p/3216267.html 今天有网友火晋地同学进了CYQ.Data官方群了,他正在折腾了一个各大ORM性能测试的比较的软件 ...

  7. java二维数组的长度

    //多少行 a.length //多少列 a[i].length

  8. Redis 在 LINUX 系统下 安装, 启动

    01, 下载  http://www.redis.cn/ ,  这里下再下来的是 redis-4.0.1.tar.gz 这个压缩包 02, 将压缩包放到 linux 系统中,  一般放在 usr/lo ...

  9. can't load package the specified module could not be found

    can't load package the specified module could not be found 用 Dependency Walker 2.2Dependency Walker ...

  10. 高性能JSON框架之FastJson的简单使用

    1.前言 1.1.FastJson的介绍: JSON协议使用方便,越来越流行,JSON的处理器有很多,这里我介绍一下FastJson,FastJson是阿里的开源框架,被不少企业使用,是一个极其优秀的 ...