您当前的位置:首页 > 新闻 > 科技

为什么阿里巴巴要禁用 Executors 创建线程池?

时间:2020-04-27 15:30:53  来源:  作者:
 

看阿里巴巴开发手册并发编程这块有一条:线程池不允许使用Executors去创建,而是通过ThreadPoolExecutor的方式,通过源码分析禁用的原因

写在前面

首先感谢大家在盖楼的间隙阅读本篇文章,通过阅读本篇文章你将了解到:

  • 线程池的定义
  • Executors创建线程池的几种方式
  • ThreadPoolExecutor对象
  • 线程池执行任务逻辑和线程池参数的关系
  • Executors创建返回ThreadPoolExecutor对象
  • OOM异常测试
  • 如何定义线程池参数

 

如果只想知道原因可以直接拉到总结那

 

线程池的定义

管理一组工作线程。通过线程池复用线程有以下几点优点:

  • 减少资源创建 => 减少内存开销,创建线程占用内存
  • 降低系统开销 => 创建线程需要时间,会延迟处理的请求
  • 提高稳定稳定性 => 避免无限创建线程引起的OutOfMemoryError【简称OOM】


Executors创建线程池的方式

根据返回的对象类型创建线程池可以分为三类:

  • 创建返回ThreadPoolExecutor对象
  • 创建返回ScheduleThreadPoolExecutor对象
  • 创建返回ForkJoinPool对象

本文只讨论创建返回ThreadPoolExecutor对象


ThreadPoolExecutor对象

在介绍Executors创建线程池方法前先介绍一下ThreadPoolExecutor,因为这些创建线程池的静态方法都是返回ThreadPoolExecutor对象,和我们手动创建ThreadPoolExecutor对象的区别就是我们不需要自己传构造函数的参数。

ThreadPoolExecutor的构造函数共有四个,但最终调用的都是同一个:

为什么阿里巴巴要禁用 Executors 创建线程池?

 

构造函数参数说明:

  • corePoolSize => 线程池核心线程数量
  • maximumPoolSize => 线程池最大数量
  • keepAliveTime => 空闲线程存活时间
  • unit => 时间单位
  • workQueue => 线程池所使用的缓冲队列
  • threadFactory => 线程池创建线程使用的工厂
  • handler => 线程池对拒绝任务的处理策略


线程池执行任务逻辑和线程池参数的关系

为什么阿里巴巴要禁用 Executors 创建线程池?

 

执行逻辑说明:

  • 判断核心线程数是否已满,核心线程数大小和corePoolSize参数有关,未满则创建线程执行任务
  • 若核心线程池已满,判断队列是否满,队列是否满和workQueue参数有关,若未满则加入队列中
  • 若队列已满,判断线程池是否已满,线程池是否已满和maximumPoolSize参数有关,若未满创建线程执行任务
  • 若线程池已满,则采用拒绝策略处理无法执执行的任务,拒绝策略和handler参数有关


Executors创建返回ThreadPoolExecutor对象

Executors创建返回ThreadPoolExecutor对象的方法共有三种:

  • Executors#newCachedThreadPool => 创建可缓存的线程池
  • Executors#newSingleThreadExecutor => 创建单线程的线程池
  • Executors#newFixedThreadPool => 创建固定长度的线程池


Executors#newCachedThreadPool方法

为什么阿里巴巴要禁用 Executors 创建线程池?

 

CachedThreadPool是一个根据需要创建新线程的线程池

 

  • corePoolSize => 0,核心线程池的数量为0
  • maximumPoolSize => Integer.MAX_VALUE,可以认为最大线程数是无限的
  • keepAliveTime => 60L
  • unit => 秒
  • workQueue => SynchronousQueue

 

当一个任务提交时,corePoolSize为0不创建核心线程,SynchronousQueue是一个不存储元素的队列,可以理解为队里永远是满的,因此最终会创建非核心线程来执行任务。对于非核心线程空闲60s时将被回收。因为Integer.MAX_VALUE非常大,可以认为是可以无限创建线程的,在资源有限的情况下容易引起OOM异常

 

Executors#newSingleThreadExecutor方法

为什么阿里巴巴要禁用 Executors 创建线程池?

 

SingleThreadExecutor是单线程线程池,只有一个核心线程

 

  • corePoolSize => 1,核心线程池的数量为1
  • maximumPoolSize => 1,只可以创建一个非核心线程
  • keepAliveTime => 0L
  • unit => 毫秒
  • workQueue => LinkedBlockingQueue

 

当一个任务提交时,首先会创建一个核心线程来执行任务,如果超过核心线程的数量,将会放入队列中,因为LinkedBlockingQueue是长度为Integer.MAX_VALUE的队列,可以认为是无界队列,因此往队列中可以插入无限多的任务,在资源有限的时候容易引起OOM异常,同时因为无界队列,maximumPoolSize和keepAliveTime参数将无效,压根就不会创建非核心线程

 

Executors#newFixedThreadPool方法

为什么阿里巴巴要禁用 Executors 创建线程池?

 

FixedThreadPool是固定核心线程的线程池,固定核心线程数由用户传入

 

  • corePoolSize => 1,核心线程池的数量为1
  • maximumPoolSize => 1,只可以创建一个非核心线程
  • keepAliveTime => 0L
  • unit => 毫秒
  • workQueue => LinkedBlockingQueue
  • 它和SingleThreadExecutor类似,唯一的区别就是核心线程数不同,并且由于使用的是LinkedBlockingQueue,在资源有限的时候容易引起OOM异常

 

总结:

 

FixedThreadPool和SingleThreadExecutor => 允许的请求队列长度为Integer.MAX_VALUE,可能会堆积大量的请求,从而引起OOM异常

CachedThreadPool => 允许创建的线程数为Integer.MAX_VALUE,可能会创建大量的线程,从而引起OOM异常

 

这就是为什么禁止使用Executors去创建线程池,而是推荐自己去创建ThreadPoolExecutor的原因

 

OOM异常测试

理论上会出现OOM异常,必须测试一波验证之前的说法:

 

测试类:TaskTest.JAVA

为什么阿里巴巴要禁用 Executors 创建线程池?

 

使用Executors创建的CachedThreadPool,往线程池中无限添加线程在启动测试类之前先将JVM内存调整小一点,不然很容易将电脑跑出问题【别问我为什么知道,是铁憨憨甜没错了!!!】,在idea里:Run -> Edit Configurations

为什么阿里巴巴要禁用 Executors 创建线程池?

 

JVM参数说明:

 

  • -Xms10M => Java Heap内存初始化值
  • -Xmx10M => Java Heap内存最大值

 

运行结果:

Exception: java.lang.OutOfMemoryError thrown from the UncaughtExceptionHandler in thread "main"
Disconnected from the target VM, address: '127.0.0.1:60416', transport: 'socket'

创建到3w多个线程的时候开始报OOM错误

 

另外两个线程池就不做测试了,测试方法一致,只是创建的线程池不一样

 

如何定义线程池参数

CPU密集型 => 线程池的大小推荐为CPU数量 + 1,CPU数量可以根据Runtime.availableProcessors方法获取

 

IO密集型 => CPU数量 * CPU利用率 * (1 + 线程等待时间/线程CPU时间)

 

混合型 => 将任务分为CPU密集型和IO密集型,然后分别使用不同的线程池去处理,从而使每个线程池可以根据各自的工作负载来调整

 

阻塞队列 => 推荐使用有界队列,有界队列有助于避免资源耗尽的情况发生

 

拒绝策略 => 默认采用的是AbortPolicy拒绝策略,直接在程序中抛出RejectedExecutionException异常【因为是运行时异常,不强制catch】,这种处理方式不够优雅。处理拒绝策略有以下几种比较推荐:

 

  • 在程序中捕获RejectedExecutionException异常,在捕获异常中对任务进行处理。针对默认拒绝策略
  • 使用CallerRunsPolicy拒绝策略,该策略会将任务交给调用execute的线程执行【一般为主线程】,此时主线程将在一段时间内不能提交任何任务,从而使工作线程处理正在执行的任务。此时提交的线程将被保存在TCP队列中,TCP队列满将会影响客户端,这是一种平缓的性能降低
  • 自定义拒绝策略,只需要实现RejectedExecutionHandler接口即可
  • 如果任务不是特别重要,使用DiscardPolicy和DiscardOldestPolicy拒绝策略将任务丢弃也是可以的

 

如果使用Executors的静态方法创建ThreadPoolExecutor对象,可以通过使用Semaphore对任务的执行进行限流也可以避免出现OOM异常。



Tags:阿里巴巴   点击:()  评论:()
声明:本站部分内容及图片来自互联网,转载是出于传递更多信息之目的,内容观点仅代表作者本人,如有任何标注错误或版权侵犯请与我们联系(Email:2595517585@qq.com),我们将及时更正、删除,谢谢。
▌相关推荐
来源 | 零壹财经作者 | Chenglin Pua元宇宙在2021年成为炙手可热的当红炸子鸡,许多公司纷纷宣布进军。国外的有“All In”元宇宙的社交巨头Meta公司。芯片设计巨头英伟达也宣...【详细内容】
2021-12-17  Tags: 阿里巴巴  点击:(10)  评论:(0)  加入收藏
那天,小二去阿里面试,面试官老王一上来就甩给了他一道面试题:为什么阿里的 Java 开发手册里会强制不要在 foreach 里进行元素的删除操作?小二听完就面露喜色,因为两年前,也就是 20...【详细内容】
2021-10-21  Tags: 阿里巴巴  点击:(42)  评论:(0)  加入收藏
企业的控制权历来是金融版新闻的话题中心,因控制权导致的纷争数也数不清。但在这么多案例中,阿里巴巴的合伙人制度一直作为股权设计的典范为人津津乐道,并且一直被模仿,但从未被...【详细内容】
2021-05-18  Tags: 阿里巴巴  点击:(117)  评论:(0)  加入收藏
一般国内散户没法买阿里的股票一般国内小散户,没有开港美通的,是没有办法直接买进在香港上市,以及在美国上市的中国企业的,比如阿里巴巴,腾讯,百度,京东,拼多多,美团,等等,几乎大部分知...【详细内容】
2021-04-14  Tags: 阿里巴巴  点击:(191)  评论:(0)  加入收藏
前言大家好,又双叒叕见面了,我是天天放大家鸽子的蛮三刀。在被大家取关之前,我立下一个“远大的理想”,一定要在这周更新文章。现在看来,flag有用了。。。本篇文章是我这一个多月...【详细内容】
2021-01-14  Tags: 阿里巴巴  点击:(192)  评论:(0)  加入收藏
刚刚,阿里巴巴达摩院发布2021十大科技趋势,这是达摩院成立三年以来第三次发布年度科技趋势。2020年是不平凡的一年,经历疫情的洗礼,许多行业重启向上而生的螺旋,但疫情并未阻挡...【详细内容】
2020-12-28  Tags: 阿里巴巴  点击:(142)  评论:(0)  加入收藏
前言众所周知,MySQL广泛应用于互联网的OLTP(联机事务处理过程)业务系统中,在大厂开发规范中,经常会看到一条"不建议使用text大字段类型”。下面就从text类型的存储结构,引发的问题...【详细内容】
2020-11-10  Tags: 阿里巴巴  点击:(100)  评论:(0)  加入收藏
想通了零售和代发要不要做的问题之后,我们就该布局店铺了。怎么布局?从客户的需求布局。比如我是代发客户,我的需求是什么,你能帮我做代发,且你要提供相关的证据链,证明你能帮我做...【详细内容】
2020-11-02  Tags: 阿里巴巴  点击:(100)  评论:(0)  加入收藏
9月17日,在2020云栖大会上,阿里云发布了第一台云电脑“无影”,突破了传统电脑的物理限制,一张“小卡片”就具备普通电脑数十倍的性能。阿里云智能总裁张建锋表示,未来每个人都可...【详细内容】
2020-09-17  Tags: 阿里巴巴  点击:(161)  评论:(0)  加入收藏
制作下拉词很有用。所谓的“下拉词”也叫推荐词。以百度为例,百度下拉框是百度为方便用户搜索而提供的关键字关联服务,提高了用户的搜索效率。大多数人在搜索关键词时不知道如...【详细内容】
2020-09-03  Tags: 阿里巴巴  点击:(111)  评论:(0)  加入收藏
▌简易百科推荐
非法购买公民信息、开发人脸认证规避技术……今年年初,广东省公安厅网安部门侦破全国首例破解“青少年防沉迷系统”的新型网络犯罪案件,抓获犯罪嫌疑人13名,查处非...【详细内容】
2021-12-28    人民日报客户端  Tags:数据安全步   点击:(5)  评论:(0)  加入收藏
就在今天,腾讯方面宣布将在2022年1月31日下架企业QQ和营销QQ,其实这一消息的降临并不让笔者意外,因为早在今年的10月28日20点之后,企业QQ和营销QQ就被停止了续费服务。相信很多...【详细内容】
2021-12-27  科技探险家    Tags:企业QQ   点击:(20)  评论:(0)  加入收藏
日前,上海交通大学发布《全球电竞之都评价报告》,对全球15个致力于发展电竞之都的城市进行评价,上海作为中国城市电竞发展的排头兵,其拥有众多优质电竞企业及完整产业集群,因此排...【详细内容】
2021-12-27  经济日报    Tags:电竞   点击:(3)  评论:(0)  加入收藏
为优化网络氛围环境,微博又开始整顿用户信息了。本月月初,微博官方发布公告,要求昵称中带有如“二货”“SB”“瘪三”“娘炮”等明显低俗或侮辱性词汇的用户尽快修改,否则将面临...【详细内容】
2021-12-24  运了个营    Tags:微博   点击:(10)  评论:(0)  加入收藏
昨日谷歌宣布,自2022年12月19日开始停止对OnHub的软件支持,OnHub路由器仍将提供Wi-Fi信号,但用户无法用谷歌Home应用程序管理它。无法更新Wi-Fi网络设置、添加额外的Wifi设备或...【详细内容】
2021-12-22  雷峰网    Tags:Google OnHub   点击:(5)  评论:(0)  加入收藏
IT之家 12 月 20 日消息,百度网盘青春版 iOS 客户端今日晚间率先开启内测,安卓客户端将在稍后内测。使用苹果 iPhone 的IT之家小伙伴可以点此下载内测版,需要先下载 TestFlight...【详细内容】
2021-12-21  IT之家    Tags:百度网盘   点击:(10)  评论:(0)  加入收藏
对于拼车单,是接还是不接,不少网约车司机表示很矛盾。接吧,钱少事多,常常跑了个寂寞,不接吧,车多客少,挑三拣四没饭吃。 在平台大力推广拼车单之下,不少司机迫于生活压力,最终还是打...【详细内容】
2021-12-17  网约车情报分享    Tags:滴滴   点击:(9)  评论:(0)  加入收藏
蓝鲸TMT频道12月16日讯,据饿了么官方微信公众号,近日,在圆桌会上,蓝骑士与平台交流了配送安全问题。饿了么表示,线上将技术手段融入安全防护;线下将持续进行安全培训,并试点智能头...【详细内容】
2021-12-17    金融界  Tags:饿了么   点击:(24)  评论:(0)  加入收藏
开源最前线(ID:OpenSourceTop) 猿妹编译项目地址: https://github.com/restic/restic全球知名代码托管平台 GitHub 今天就重磅发布了今年的年度报告——《2021 年度 O...【详细内容】
2021-12-17  Python部落    Tags:   点击:(9)  评论:(0)  加入收藏
新京报快讯 据中国网络视听节目服务协会网站消息,12月15日,中国网络视听节目服务协会发布了《网络短视频内容审核标准细则》(2021)。中国网络视听节目服务协会组织有关短视频平...【详细内容】
2021-12-16    新京报  Tags:短视频   点击:(11)  评论:(0)  加入收藏
最新更新
栏目热门
栏目头条