阿里代码规约为什么不让使用Executors包装好线程池呢?
时间:2022-07-24
本文章向大家介绍阿里代码规约为什么不让使用Executors包装好线程池呢?,主要内容包括其使用实例、应用技巧、基本知识点总结和需要注意事项,具有一定的参考价值,需要的朋友可以参考一下。
在Executors下主要有5个静态方法:
1. Executors.newWorkStealingPool
- JDK8引入,创建持有足够线程的线程池支持给定的并行度,并通过使用多个队列减少竞争,此构造方法把CPU数量设置为默认的并行度
public ForkJoinPool(int parallelism,
ForkJoinWorkerThreadFactory factory,
UncaughtExceptionHandler handler,
boolean asyncMode) {
this(checkParallelism(parallelism),
checkFactory(factory),
handler,
asyncMode ? FIFO_QUEUE : LIFO_QUEUE,
"ForkJoinPool-" + nextPoolId() + "-worker-");
checkPermission();
}
2. Executors.newCacheThreadPool
- 这个线程池是一个没有核心线程数的,且最大线程数是Integer.MAX_VALUE,且使用的队列是SynchronousQueue,这个队列有点反人类,他不存储元素的阻塞队列,在创建元素的时候每一个put操作必须等待take操作,否则就不能添加元素 。这样我们就知道了因为没有核心线程数,所以刚来的任务我们都会进入到队列中,但是这个队列没有take也不会put,此时那就是说队列满了,然后就创建最大线程数。且设置的最大线程数在空闲状态下的存活时间为60秒。当有线程闲下来的时候,如果有新的任务来的时候就是用空闲线程,但是有可能出现瞬间来了大量的请求,此时就会无限创建线程直到Integer.MAX_VALUE个线程,很多机器应该在没有达到之前就会OOM了。创建一个线程就会分配堆,本地方法栈,java虚拟机栈等。所以就很容易就OOM了
public static ExecutorService newCachedThreadPool() {
return new ThreadPoolExecutor(0, Integer.MAX_VALUE,
60L, TimeUnit.SECONDS,
new SynchronousQueue<Runnable>());
}
3. Executors.newScheduledThreadPool
- 线程数最大到Integer.MAX_VALUE,与上面所说的一样都有可能会OOM,他是ScheduledExecutorService接口家族的实现类,支持定时及周期性任务执行。与newCacheThreadPool的区别就是不回收工作线程。从下面代码可以看出到最后也是使用了ThreadPoolExcutor这个类然定义了对应对参数。如设置了最大线程数的存活时间是0秒。
public static ScheduledExecutorService newScheduledThreadPool(int corePoolSize) {
return new ScheduledThreadPoolExecutor(corePoolSize);
}
public ScheduledThreadPoolExecutor(int corePoolSize) {
super(corePoolSize, Integer.MAX_VALUE, 0, NANOSECONDS,
new DelayedWorkQueue());
}
public ThreadPoolExecutor(int corePoolSize,
int maximumPoolSize,
long keepAliveTime,
TimeUnit unit,
BlockingQueue<Runnable> workQueue) {
this(corePoolSize, maximumPoolSize, keepAliveTime, unit, workQueue,
Executors.defaultThreadFactory(), defaultHandler);
}
4. Executors.newSingleThreadExecutor
- 创建一个单线程的的线程池,相当于单线程串行执行任务,保证按任务的提交顺序依次执行。这个线程池虽然不会因为线程创建过多而oom但是会因为阻塞到队列而最后产生oom,因为他使用的是LinkedBlockingQueue 看源码我们可知他的最大长度也是Integer.MAX_VALUE,所以大量任務的提交也会导致OOM。
源码:
public static ExecutorService newSingleThreadExecutor() {
return new FinalizableDelegatedExecutorService
(new ThreadPoolExecutor(1, 1,
0L, TimeUnit.MILLISECONDS,
new LinkedBlockingQueue<Runnable>()));
}
5. Executors.newFixedThreadPool
- 输入的参数即是固定的线程数,即是核心的线程数也是最大的线程数,不存在空闲线程
- 看下面的源码我们可知最大线程数和核心线程数是相等的,也就可说只有核心线程数,我们都知道如果核心线程数没有特定的配置的话核心线程数一旦创建就不会被回收的。但是我们可以看到他使用的也是LinkedBlockingQueue且默认的大小为Integer.MAX_VALUE,所以也会OOM。
public static ExecutorService newFixedThreadPool(int nThreads) {
return new ThreadPoolExecutor(nThreads, nThreads,
0L, TimeUnit.MILLISECONDS,
new LinkedBlockingQueue<Runnable>());
}
其实看了上面的Excutors的五个方法后,在阿里规约里面时不可以使用除第一个外的四个包内线程的,因为他们都会引起OOM。
从源码我们可以看出都是有ThreadPoolExcutor这个类传入不同的参数而实现的所以说只要我们搞懂其中传入的7个参数的含义,就可以大概搞懂线程池的冰山一角了
- Spring Cloud构建微服务架构:分布式服务跟踪(抽样收集)【Dalston版】
- HBase client访问ZooKeeper获取root-region-server DeadLock问题(zookeeper.ClientCnxn Unable to get data of zn
- zookeeper学习系列:四、Paxos算法和zookeeper的关系
- 有了phonegap你还android吗?
- zookeeper学习系列:三、利用zookeeper做选举和锁
- Spring Cloud构建微服务架构:分布式服务跟踪(收集原理)【Dalston版】
- zookeeper学习系列:二、api实践
- Spring Cloud构建微服务架构:分布式服务跟踪(整合logstash)【Dalston版】
- Spring Cloud构建微服务架构:分布式服务跟踪(整合zipkin)【Dalston版】
- 困扰我多年的Connection reset问题
- scala学习笔记
- jersey处理支付宝异步回调通知的问题:java.lang.IllegalArgumentException: Error parsing media type 'application/x-www
- 使用 Java Service Wrapper 启动java后台进程服务
- PHP码农在Golang压力下的生存之道-PHP性能优化实践
- JavaScript 教程
- JavaScript 编辑工具
- JavaScript 与HTML
- JavaScript 与Java
- JavaScript 数据结构
- JavaScript 基本数据类型
- JavaScript 特殊数据类型
- JavaScript 运算符
- JavaScript typeof 运算符
- JavaScript 表达式
- JavaScript 类型转换
- JavaScript 基本语法
- JavaScript 注释
- Javascript 基本处理流程
- Javascript 选择结构
- Javascript if 语句
- Javascript if 语句的嵌套
- Javascript switch 语句
- Javascript 循环结构
- Javascript 循环结构实例
- Javascript 跳转语句
- Javascript 控制语句总结
- Javascript 函数介绍
- Javascript 函数的定义
- Javascript 函数调用
- Javascript 几种特殊的函数
- JavaScript 内置函数简介
- Javascript eval() 函数
- Javascript isFinite() 函数
- Javascript isNaN() 函数
- parseInt() 与 parseFloat()
- escape() 与 unescape()
- Javascript 字符串介绍
- Javascript length属性
- javascript 字符串函数
- Javascript 日期对象简介
- Javascript 日期对象用途
- Date 对象属性和方法
- Javascript 数组是什么
- Javascript 创建数组
- Javascript 数组赋值与取值
- Javascript 数组属性和方法
- PHP whois查询类定义与用法示例
- Laravel多域名下字段验证的方法
- ThinkPHP框架整合微信支付之Native 扫码支付模式二图文详解
- 简单了解如何封装自己的Python包
- python求解汉诺塔游戏
- Python第三方包PrettyTable安装及用法解析
- 如何让python的运行速度得到提升
- 在keras中对单一输入图像进行预测并返回预测结果操作
- python中数字是否为可变类型
- ThinkPHP3.2.3框架实现的空模块、空控制器、空操作,跳转到错误404页面图文详解
- PHP示例演示发送邮件给某个邮箱
- PHP设计模式之观察者模式定义与用法分析
- PHP实现数组向任意位置插入,删除,替换数据操作示例
- 实例讲解Python 迭代器与生成器
- opencv 图像轮廓的实现示例