Java ThreadPoolExecutor的参数深入理解

一、使用Executors创建线程池
之前创建线程的时候都是用的Executors的newFixedThreadPool(),newSingleThreadExecutor(),newCachedThreadPool()这三个方法。当然Executors也是用不同的参数去new ThreadPoolExecutor
1. newFixedThreadPool()
创建线程数固定大小的线程池。 由于使用了LinkedBlockingQueue所以maximumPoolSize 没用,当corePoolSize满了之后就加入到LinkedBlockingQueue队列中。每当某个线程执行完成之后就从LinkedBlockingQueue队列中取一个。所以这个是创建固定大小的线程池。
public static ExecutorService newFixedThreadPool(int nThreads) {
return new ThreadPoolExecutor(nThreads, nThreads,
0L, TimeUnit.MILLISECONDS,
new LinkedBlockingQueue<Runnable>());
}
public ThreadPoolExecutor(int corePoolSize,
int maximumPoolSize,
long keepAliveTime,
TimeUnit unit,
BlockingQueue<Runnable> workQueue) {
this(corePoolSize, maximumPoolSize, keepAliveTime, unit, workQueue,
Executors.defaultThreadFactory(), defaultHandler);
}
2.newSingleThreadPool()
创建线程数为1的线程池,由于使用了LinkedBlockingQueue所以maximumPoolSize 没用,corePoolSize为1表示线程数大小为1,满了就放入队列中,执行完了就从队列取一个。
public static ExecutorService newSingleThreadExecutor() {
return new FinalizableDelegatedExecutorService
(new ThreadPoolExecutor(1, 1,
0L, TimeUnit.MILLISECONDS,
new LinkedBlockingQueue<Runnable>()));
}
3.newCachedThreadPool()
创建可缓冲的线程池。没有大小限制。由于corePoolSize为0所以任务会放入SynchronousQueue队列中,SynchronousQueue只能存放大小为1,所以会立刻新起线程,由于maxumumPoolSize为Integer.MAX_VALUE所以可以认为大小为2147483647。受内存大小限制。
public static ExecutorService newCachedThreadPool() {
return new ThreadPoolExecutor(0, Integer.MAX_VALUE,
60L, TimeUnit.SECONDS,
new SynchronousQueue<Runnable>());
}
public ThreadPoolExecutor(int corePoolSize,
int maximumPoolSize,
long keepAliveTime,
TimeUnit unit,
BlockingQueue<Runnable> workQueue) {
this(corePoolSize, maximumPoolSize, keepAliveTime, unit, workQueue,
Executors.defaultThreadFactory(), defaultHandler);
}
二、使用ThreadPoolExecutor创建线程池
ThreadPoolExecutor的构造函数
public ThreadPoolExecutor(int corePoolSize,
int maximumPoolSize,
long keepAliveTime,
TimeUnit unit,
BlockingQueue<Runnable> workQueue,
ThreadFactory threadFactory,
RejectedExecutionHandler handler) {
if (corePoolSize < 0 ||
maximumPoolSize <= 0 ||
maximumPoolSize < corePoolSize ||
keepAliveTime < 0)
throw new IllegalArgumentException();
if (workQueue == null || threadFactory == null || handler == null)
throw new NullPointerException();
this.corePoolSize = corePoolSize;
this.maximumPoolSize = maximumPoolSize;
this.workQueue = workQueue;
this.keepAliveTime = unit.toNanos(keepAliveTime);
this.threadFactory = threadFactory;
this.handler = handler;
}
参数:
1、corePoolSize核心线程数大小,当线程数<corePoolSize ,会创建线程执行runnable
2、maximumPoolSize 最大线程数, 当线程数 >= corePoolSize的时候,会把runnable放入workQueue中
3、keepAliveTime 保持存活时间,当线程数大于corePoolSize的空闲线程能保持的最大时间。
4、unit 时间单位
5、workQueue 保存任务的阻塞队列
6、threadFactory 创建线程的工厂
7、handler 拒绝策略
任务执行顺序:
1、当线程数小于corePoolSize时,创建线程执行任务。
2、当线程数大于等于corePoolSize并且workQueue没有满时,放入workQueue中
3、线程数大于等于corePoolSize并且当workQueue满时,新任务新建线程运行,线程总数要小于maximumPoolSize
4、当线程总数等于maximumPoolSize并且workQueue满了的时候执行handler的rejectedExecution。也就是拒绝策略。
ThreadPoolExecutor默认有四个拒绝策略:
1、ThreadPoolExecutor.AbortPolicy() 直接抛出异常RejectedExecutionException
2、ThreadPoolExecutor.CallerRunsPolicy() 直接调用run方法并且阻塞执行
3、ThreadPoolExecutor.DiscardPolicy() 直接丢弃后来的任务
4、ThreadPoolExecutor.DiscardOldestPolicy() 丢弃在队列中队首的任务
当然可以自己继承RejectedExecutionHandler来写拒绝策略.
int corePoolSize = 1;
int maximumPoolSize = 2;
int keepAliveTime = 10;
// BlockingQueue<Runnable> workQueue = new LinkedBlockingQueue<Runnable>();
BlockingQueue<Runnable> workQueue = new ArrayBlockingQueue<Runnable>(5);
ThreadFactory threadFactory = Executors.defaultThreadFactory();
//线程池和队列满了之后的处理方式
//1.跑出异常
RejectedExecutionHandler handler = new ThreadPoolExecutor.AbortPolicy();
RejectedExecutionHandler handler2 = new ThreadPoolExecutor.CallerRunsPolicy();
RejectedExecutionHandler handler3 = new ThreadPoolExecutor.DiscardPolicy();
RejectedExecutionHandler handler4 = new ThreadPoolExecutor.DiscardOldestPolicy();
ThreadPoolExecutor threadPoolExecutor = new ThreadPoolExecutor(corePoolSize, maximumPoolSize, keepAliveTime, TimeUnit.SECONDS, workQueue, threadFactory, handler2);
for (int j = 1; j < 15; j++) {
threadPoolExecutor.execute(new Runnable() {
public void run() {
try {
System.out.println(Thread.currentThread().getName());
TimeUnit.SECONDS.sleep(1);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
});
}
System.out.println(threadPoolExecutor);
}
感谢阅读,希望能帮助到大家,谢谢大家对本站的支持!
# Java
# ThreadPoolExecutor参数理解
# ThreadPoolExecutor参数详解
# Java线程池的拒绝策略实现详解
# 详解什么是Java线程池的拒绝策略?
# Java线程池ThreadPoolExecutor原理及使用实例
# ThreadPoolExecutor线程池的使用方法
# 线程池ThreadPoolExecutor使用简介与方法实例
# Skywalking改成适配阿里云等带Http Basic的Elasticsearch服务
# 满了
# 都是
# 使用了
# 希望能
# 会把
# 谢谢大家
# 跑出
# 这三个
# 抛出
# 来写
# 数为
# 中取
# 新任务
# 直接调用
# return
# TimeUnit
# MILLISECONDS
# static
# public
# ExecutorService
相关文章:
赚钱网站制作软件,建一个网站怎样才能赚钱?是如何盈利的?
如何基于PHP生成高效IDC网络公司建站源码?
C++中的Pimpl idiom是什么,有什么好处?(隐藏实现)
如何在Mac上搭建Golang开发环境_使用Homebrew安装和管理Go版本
家庭服务器如何搭建个人网站?
制作网站的公司有哪些,做一个公司网站要多少钱?
建站之星在线版空间:自助建站+智能模板一键生成方案
网站制作知乎推荐,想做自己的网站用什么工具比较好?
如何通过WDCP绑定主域名及创建子域名站点?
深圳网站制作的公司有哪些,dido官方网站?
,怎么用自己头像做动态表情包?
大连网站制作费用,大连新青年网站,五年四班里的视频怎样下载啊?
网站制作公司排行榜,抖音怎样做个人官方网站
建站之星安装步骤有哪些常见问题?
大型企业网站制作流程,做网站需要注册公司吗?
如何在IIS中新建站点并配置端口与物理路径?
制作宣传网站的软件,小红书可以宣传网站吗?
简历在线制作网站免费版,如何创建个人简历?
油猴 教程,油猴搜脚本为什么会网页无法显示?
免费公司网站制作软件,如何申请免费主页空间做自己的网站?
C++ static_cast和dynamic_cast区别_C++静态转换与动态类型安全转换
制作网站建设的公司有哪些,网站建设比较好的公司都有哪些?
香港服务器部署网站为何提示未备案?
建站之星伪静态规则如何正确配置?
高性价比服务器租赁——企业级配置与24小时运维服务
西安市网站制作公司,哪个相亲网站比较好?西安比较好的相亲网站?
如何获取PHP WAP自助建站系统源码?
如何用好域名打造高点击率的自主建站?
html制作网站的步骤有哪些,iapp如何添加网页?
建站之星展会模板:智能建站与自助搭建高效解决方案
如何快速生成ASP一键建站模板并优化安全性?
如何配置IIS站点权限与局域网访问?
如何选择PHP开源工具快速搭建网站?
c# Task.Yield 的作用是什么 它和Task.Delay(1)有区别吗
已有域名能否直接搭建网站?
详解ASP.NET 生成二维码实例(采用ThoughtWorks.QRCode和QrCode.Net两种方式)
广州营销型建站服务商推荐:技术优势与SEO优化解析
打鱼网站制作软件,波克捕鱼官方号怎么注册?
家具网站制作软件,家具厂怎么跑业务?
如何选购建站域名与空间?自助平台全解析
C#如何在一个XML文件中查找并替换文本内容
新网站制作渠道有哪些,跪求一个无线渠道比较强的小说网站,我要发表小说?
网站设计制作企业有哪些,抖音官网主页怎么设置?
建站之星如何修改网站生成路径?
seo网站制作优化,网站SEO优化步骤有哪些?
建站之星手机一键生成:多端自适应+小程序开发快速建站指南
建站之星Pro快速搭建教程:模板选择与功能配置指南
如何在IIS中配置站点IP、端口及主机头?
网站制作公司,橙子建站是合法的吗?
建站IDE高效指南:快速搭建+SEO优化+自适应模板全解析
*请认真填写需求信息,我们会在24小时内与您取得联系。