当前位置: 首页 > news >正文

Java使用默认线程池的陷阱问题

我们都知道JDK1.5之后提供了ThreadPoolExecutor类,可以用来自定义线程池。

线程池有很多好处,比如:

减少资源消耗,避免频繁创建和销毁线程,可以直接复用已有线程。
提供速度,任务来了之后,因为线程已经存在,可以直接使用。
提高线程的可管理性。线程是非常宝贵的资源。如果创建的线程过多,不仅会消耗系统资源,甚至会影响系统的稳定性。
使用线程池,可以非常方便地创建、管理和监控线程。
该类包含许多静态方法:

newCachedThreadPool: 创建一个可缓冲线程。如果线程池的大小超过处理需要,可以灵活回收空闲线程。如果没有回收,则创建一个新线程。
newFixedThreadPool:创建一个固定大小的线程池。如果任务数量超过线程池大小,则将多余的任务放入队列中。
newScheduledThreadPool:创建一个固定大小的线程池,可以执行定时的周期性任务。
newSingleThreadExecutor:创建一个只有一个线程的线程池,保证所有任务按顺序安装和执行。
在高并发场景下,如果使用这些静态方法来创建线程池,会出现一些问题。

那么,让我们看看存在哪些问题。

newFixedThreadPool:允许请求的队列长度为Integer.MAX_VALUE,可能会堆积大量请求,导致OOM。
newSingleThreadExecutor:请求允许的队列长度为Integer.MAX_VALUE,可能会堆积大量请求,导致OOM。
newCachedThreadPool: 允许创建的线程数为Integer.MAX_VALUE,可能会创建大量线程,导致OOM。
那么我们应该怎么做呢?

建议先使用ThreadPoolExecutor类,我们自定义线程池。

具体代码如下:

ExecutorService threadPool = <b>new</b> ThreadPoolExecutor(
    8, <font><i>//The number of core threads in the corePoolSize thread pool</i></font><font>
    10, </font><font><i>//maximumPoolSize The maximum number of threads in the thread pool</i></font><font>
    60, </font><font><i>//The maximum idle time of threads in the thread pool, after which idle threads will be recycled</i></font><font>
    TimeUnit.SECONDS,</font><font><i>//time unit</i></font><font>
    <b>new</b> ArrayBlockingQueue(500), </font><font><i>//queue</i></font><font>
    <b>new</b> ThreadPoolExecutor.CallerRunsPolicy()); </font><font><i>//rejection policy</i></font><font>
</font>

顺便说一句,如果是一些低并发的场景,使用Executors类创建线程池也不是不行,也不是所有场景都可以使用。

在这些低并发场景中,很难出现OOM问题,所以我们需要根据实际业务场景进行选择。

相关文章:

  • Android12启动崩溃 no namespace called
  • 【HTML——旋转晕眩】(效果+代码)
  • codeblocks安装、使用、调试教程
  • 交换机与路由技术-32-命名ACL
  • 互联网大厂技术岗实习/求职经验分享(实习内推+简历+面试+offer)
  • Java中的数组以及八大排序算法
  • zabbix分布式
  • [math]判断线段是否相交及夹角
  • 如何并行化普通的python代码
  • 人力资源团队怎样利用智能科技提升工作效率
  • 对角线的输出
  • Charles乱码和SSL 代理问题解决
  • SharedPreference使用
  • Javaweb安全——Shiro漏洞利用
  • java基本微信小程序的高校科研管理系统 uniapp小程序
  • 【译】JS基础算法脚本:字符串结尾
  • 分享一款快速APP功能测试工具
  • JS正则表达式精简教程(JavaScript RegExp 对象)
  • mysql中InnoDB引擎中页的概念
  • react-core-image-upload 一款轻量级图片上传裁剪插件
  • Spring技术内幕笔记(2):Spring MVC 与 Web
  • vue-loader 源码解析系列之 selector
  • 阿里云购买磁盘后挂载
  • 动手做个聊天室,前端工程师百无聊赖的人生
  • 简单实现一个textarea自适应高度
  • 简单易用的leetcode开发测试工具(npm)
  • 推荐一款sublime text 3 支持JSX和es201x 代码格式化的插件
  • 我的面试准备过程--容器(更新中)
  • 想晋级高级工程师只知道表面是不够的!Git内部原理介绍
  • 消息队列系列二(IOT中消息队列的应用)
  • 自动记录MySQL慢查询快照脚本
  • postgresql行列转换函数
  • ​一、什么是射频识别?二、射频识别系统组成及工作原理三、射频识别系统分类四、RFID与物联网​
  • # Swust 12th acm 邀请赛# [ A ] A+B problem [题解]
  • # Swust 12th acm 邀请赛# [ K ] 三角形判定 [题解]
  • # 学号 2017-2018-20172309 《程序设计与数据结构》实验三报告
  • # 再次尝试 连接失败_无线WiFi无法连接到网络怎么办【解决方法】
  • #设计模式#4.6 Flyweight(享元) 对象结构型模式
  • #我与Java虚拟机的故事#连载10: 如何在阿里、腾讯、百度、及字节跳动等公司面试中脱颖而出...
  • $ git push -u origin master 推送到远程库出错
  • $var=htmlencode(“‘);alert(‘2“); 的个人理解
  • (1)Android开发优化---------UI优化
  • (1综述)从零开始的嵌入式图像图像处理(PI+QT+OpenCV)实战演练
  • (done) ROC曲线 和 AUC值 分别是什么?
  • (Redis使用系列) Springboot 实现Redis 同数据源动态切换db 八
  • (八)Spring源码解析:Spring MVC
  • (二)linux使用docker容器运行mysql
  • (二)学习JVM —— 垃圾回收机制
  • (九)信息融合方式简介
  • (每日持续更新)jdk api之FileReader基础、应用、实战
  • (十)c52学习之旅-定时器实验
  • (转)Sql Server 保留几位小数的两种做法
  • (转)德国人的记事本
  • (转)母版页和相对路径
  • **PHP分步表单提交思路(分页表单提交)