网站首页 > java教程 正文
默认的线程池使用起来有不少的风险,比如容易OOM,所以一般我们不使用系统的默认的线程池,需要自己根据业务特点来定制线程池。 定制线程池无非是关注线程池的几个参数
一 核心线程数
核心线程数即corePoolSize ,如果是cpu密集的任务,核心线程数设置为cpu核心的1-2倍,如果是io密集的任务,设置的线程数为2倍以上,具体可以根据公式评估下: 《Java并发编程实战》的作者 Brain Goetz 推荐的计算方法: 线程数 = CPU 核心数 *(1+平均等待时间/平均工作时间) 通过这个公式,如果我们任务的等待时间比较长(IO密集型),那么线程数就多,如果平均工作时间比较长(CPU密集型),那线程数就少。 线程数少了无法充分利用系统资源,线程数多了调度频繁,上下文切换比较多,反而会降低性能,具体设置多少,我们还可以通过监控JVM线程数和cpu的负载情况,来设定合适的线程数。
最大线程数一般设置为核心线程数的几倍,以便可以达到更好的应对突发的情况。
二 阻塞队列
阻塞队列我们可以选择java线程池里面常用的几个队列:LinkedBlockingQueue 或者 SynchronousQueue 或者 DelayedWorkQueue。不过更推荐使用ArrayBlockingQueue,这个队列内部是通过数组来实现的,它最大的特点是有容量限制,一旦设置了不可以修改,如果线程池的线程数量已经达到了最大线程数,且队列也满了,后续的任务都会按照拒绝策略进行拒绝了,但是对于无限制增加线程数或者队列容量不限制的场景,ArrayBlockingQueue队列加上限制了最大线程数据,防止了程序占用内存太多,而导致的OOM问题。
如果我们使用容量更大的队列和更小的最大线程数,就可以减少上下文切换带来的开销,但也可能因此降低整体的吞吐量;如果我们的任务是 IO 密集型,则可以选择稍小容量的队列和更大的最大线程数,这样整体的效率就会更高,不过也会带来更多的上下文切换。
三 线程工厂
定制线程工厂的目的是为了让线程名变的可以识别,可以根据任务名称来设置线程名。 比如可以通过com.google.common.util.concurrent.ThreadFactory Builder 来实现,如代码所示。
ThreadFactoryBuilder builder = new ThreadFactoryBuilder();
ThreadFactory calFactory = builder.setNameFormat("cal-pool-%d").build();
这样生成的线程名称为: cal-pool-1,cal-pool-2等
四 拒绝策略
默认的实现的四种策略AbortPolicy,DiscardPolicy,DiscardOldestPolicy 或者 CallerRunsPolicy 我们一般会选择CallerRunsPolicy 策略或AbortPolicy更合适点,还可以通过实现RejectedExecutionHandler 接口来实现自己的拒绝策略 ,如下:
private static class CustomMyRejectionHandler implements RejectedExecutionHandler {
@Override
public void rejectedExecution(Runnable r, ThreadPoolExecutor executor) {
// 打印 临时存储啊
}
}
我们通过实现rejectedExecution这个接口来自定义拒绝策略。
猜你喜欢
- 2024-11-23 不清楚Java线程池实现原理?那你应该收藏这篇文章!「源码分析」
- 2024-11-23 Java基础——Java多线程(线程的创建方式)
- 2024-11-23 「一文搞懂」Java线程池实现原理
- 2024-11-23 Java线程池
- 2024-11-23 java线程池实现原理以及应用场景说明
- 2024-11-23 快速弄懂Java线程池
- 2024-11-23 java线程池原理浅析
- 2024-11-23 彻底了解线程池的原理——40行从零开始自己写线程池
- 2024-11-23 Java并发编程(8):Executor框架 - 可扩展线程池WorkStealingPool
- 2024-11-23 java中的线程池
你 发表评论:
欢迎- 最近发表
-
- 五,网络安全IDA Pro反汇编工具初识及逆向工程解密实战
- 「JAVA8」- Lambda 表达式(java lambda表达式原理)
- 深入探讨Java代码保护:虚拟机保护技术的新时代
- Nginx反向代理原理详解(图文全面总结)
- 逆向拆解日本IT,哪些Java技术栈薪资溢价高
- mybatis 逆向工程使用姿势不对,把表清空了,心里慌的一比
- Spring Boot集成ProGuard轻松实现Java 代码混淆, Java 应用固若金汤
- 从 Java 代码逆向工程生成 UML 类图和序列图
- 人与人相处:尊重是标配,靠谱是高配,厚道是顶配
- Windows系统安装日期如何修改(windows10怎么修改安装日期)
- 标签列表
-
- java反编译工具 (77)
- java反射 (57)
- java接口 (61)
- java随机数 (63)
- java7下载 (59)
- java数据结构 (61)
- java 三目运算符 (65)
- java对象转map (63)
- Java继承 (69)
- java字符串替换 (60)
- 快速排序java (59)
- java并发编程 (58)
- java api文档 (60)
- centos安装java (57)
- java调用webservice接口 (61)
- java深拷贝 (61)
- 工厂模式java (59)
- java代理模式 (59)
- java.lang (57)
- java连接mysql数据库 (67)
- java重载 (68)
- java 循环语句 (66)
- java反序列化 (58)
- java时间函数 (60)
- java是值传递还是引用传递 (62)
本文暂时没有评论,来添加一个吧(●'◡'●)