Java线程池配置由繁至简,找到适合自己的天命线程池

Java线程池配置由繁至简,找到适合自己的天命线程池

任务队列workQueue和饱和策略handler什么时候登场?

  • 首先这里有几道经常考的线程池面试题:
    • 简单介绍下线程池,核心数从corePoolSize 到maximumPoolSize 的变化过程?
    • 线程池在什么时机会执行饱和策略?
    • 当线程池的任务队列满之后,就会执行对应的饱和策略吗?
  • 这些问题其实说到底都是在考线程池的执行步骤,当你弄懂这些时机和条件后,我相信你可以融会贯通整套流程。
  • 我们这里先引入流程图看一下:
  • img
  • 只看流程图可能不容易理解,我们下面用一个示例来演示一下整个流程:
  • 首先我们假设几个参数,corePoolSize 核心线程为5,maximumPoolSize 最大线程数为10,workQueue 任务队列的容量为20,还需要用activeCount来表示正在工作的线程(下面简写为工作线程),为了兜底,所以假设任务一直在添加,由于很耗时,程序hold不住,一直到执行饱和策略的环节。
    • 假设不断地有任务进来,程序就会增加工作线程来处理任务,即activeCount增加,会一直增加到corePoolSize,直到满足第一个条件“核心线程池已满”,即activeCount=corePoolSize=5。
    • 这时再追加任务,程序就会把任务放进任务队列workQueue,工作线程处理完当前任务,就会按FIFO先入先出的顺序,从任务队列workQueue里拿出任务继续做;随着任务的放入,workQueue.size()会逐渐增大,一直到满足第二个条件“任务队列已满”,即workQueue.size()=20,activeCount此时仍为5。
    • 再继续追加任务,程序就会在corePoolSize的基数上继续增加工作线程,即activeCount从5开始增加,一直到满足第三个条件“最大线程池已满”,即activeCount=maximumPoolSize=10。
    • 此时我们看一下参数值,activeCount=maximumPoolSize=10,workQueue.size()=20,能满的已经全满了,表示程序已经达到了最大的上限,后面再追加的任务就会去执行饱和策略。

饱和策略有哪些?哪个更适合我?

  • 我们先来回顾下饱和策略的意义——由于达到线程边界和队列容量而阻塞执行时使用的处理程序。
  • 可以简单地用一句话来解释:任务队列满 & 工作线程数已经增加到最大核心数,此时再新增进任务,便会对任务执行对应的处理。
  • img

AbortPolicy

  • Abort->退出、终止;满足条件时会直接抛出****RejectedExecutionException异常,它也是ThreadPoolExecutor默认的饱和策略;但同时由于他的简单粗暴,程序可能会因此中断,所以虽然是默认的饱和策略,但如果要用,务必做好异常处理

CallerRunsPolicy

  • 满足条件时,会直接调用当前主线程去执行任务,比如你在main方法执行了线程池,策略的缺点就是可能会阻塞主线程,影响性能

DiscardPolicy

  • Discard->丢弃,抛弃;这个是最简单粗暴的饱和策略,直接扔掉,满了之后再来的任务统统扔掉!对一些不重要,或者时效性比完整性优先级高的任务还是挺好用的,但如果你对任务的完整性要求高,不建议使用。

DiscardOldestPolicy

  • 比上个策略多了一个oldest,意思就是 FIFO 先入先出,当满足条件时,会优先丢弃队列里最旧即最早的任务数据,所以同样的,如果你对任务的完整性要求高,不建议使用。

这么比较下来,相信你心里已经有了答案:

  • 如果你对任务的完整性要求很高,一条数据都不能丢,比对性能的要求高,那合适的选择就是CallerRunsPolicy。
  • 如果你对性能要求很高,数据少或多都还能接受,就可以选择其他三个饱和策略,丢弃或者对异常进行处理。
  • 你可能会说:性能和完整性,我全都要!
  • 那怎么办呢?有什么办法吗?
  • 我的答案是:当然有,它既然叫饱和策略,肯定是满足条件后才会走到这一步,相当于最后的保底措施,所以在一定情况下,假如根据程序配好了其他参数,是根本不会走到饱和策略这一步的,我们要做的就是:调整好其他参数,饱和策略是最后的底牌,尽量不要触发。

核心线程数和最大线程数到底设置多少?

  • 从上面一系列介绍中,我们知道任务队列和饱和策略都有了推荐,但其实大家伙最关心也是最疑惑的就是核心线程数和最大线程数的设置。
  • 你可能在这之前翻过很多文章,有人说设置为服务器核心数N,有人说应该是服务器核心数N+1,有人说要判断是I/O密集型就2N,计算密集型的话就N+1,都很有理论依据,我曾经也为这个所苦恼。
  • 其实连带的还有一些问题,比如每台服务器的情况不一样,有的可能同时跑得有tomcat,有的可能还有有别的服务,这个时候上面的理论配置是否还适合我们?
  • 在经过翻查无数次的资料与文章后,一篇美团在2020年发布的名为《Java线程池实现原理及其在美团业务中的实践》的文章让我眼前一亮:既然参数在每个服务器上都不确定,那我改成动态配置的不就可以了吗?不够我就加,多了我就减。
  • 可惜美团只提供了思路,并没有把代码开源出来(行了吧,还要啥自行车?
  • 但是并不妨碍网上的大佬多,已经有个人开发者把这套逻辑整理出来并开源,没错,我也已经上车了,真香!如果你想了解,可以搜索“动态线程池配置”这些关键词,我在这里就不打广告了。
JOJO!这是我最后的项目示例了!
  • 拿我自己的经历举个例子,阿里云4核8G的机器,单机任务的峰值QPS大概为2000左右,虽然不高,但由于线程池执行的任务都是从别家服务器获取响应,所以容易堆积,设置了最大超时时间200ms。
  • 最早一版的配置是5/16/2000(corePoolSize/maximumPoolSize/workQueue.capacity),无奈不到高峰期就报警。
  • 后赶紧调整参数到8/16/2000,当时倒是不报警了,但在后面增加了策略配置后(即并发任务量增加)又出现了报警。
  • 最后调整到16/32/2000,依旧报警,没错,不光N+1、2N,都已经N^2,它还是报警。
  • img
  • 这时我意识到很多情况,可能是网络问题,可能是因为服务还有其他的线程池,也可能是已经到了线程池性能的瓶颈,所以并没有对参数进行进一步的调整。
  • 但玄学的事情发生了:在这波报警后,后面就再也没有发生过报警了,也观察了线程池日志,发现工作线程activeCount最大也只到了16,2000容量的任务队列也只用到几十到一百多个,一切好像都归于了平静,于是参数也没有再进行修改了,似乎已经找到了最合适的参数。
  • 好的,如果你看到这里,那么现在这个例子已经是你的了。

最后的建议

  • 在面试时,记住八股文,知道I/O密集型和计算密集型的理论值场景,但在跟面试官讲述时可以加上自己项目的例子,实在没有就可以说上面这个。
  • 在实际的项目运用中,结合项目情况,最好加上动态线程池配置。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/632983.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

我用 ChatGPT 做了一次探索性数据分析,真的太太太实用了!

ChatGPT 经过短短1年时间的发展,其功能越来越强,现在已经是大多数企业和个人不可或缺的助手。特别是最新的 GPT-4 版本,专门在左边菜单栏给出了两个工具(一个是数据分析,另一个是根据文字描述生成图片)&…

教育的本质与教师发展:对能力大赛模板化现象的深度反思与批判——以快速技术迭代背景下的教学策略为审视视角

在我国当前的教育体系中,教师能力大赛等活动在一定程度上确实扮演了提升教师专业素养、推动教学改革的角色。它们通过竞争机制激发了教师自我提升的动力,并提供了一个展示教师教学才华的平台。然而,随着时间推移,此类活动却呈现出…

Opencv小项目——手势数字刷TIKTOK

​ 写在前面: 很久没更新了,之前的实习的记录也算是烂尾了,但是好在自己的实习记录还是有的,最近也忙碌了很多,终于放假了,今天下午正好没事,闲来无事就随便做个小玩意吧。 思来想去&#xff…

yolo9000:Better, Faster, Stronger的目标检测网络

目录 一、回顾yolov1二、yolov2详细讲解2.1 Better部分创新点(1)Batch Normalization(批量归一化)(2)High Resolution Classifier---高分辨率分类器(3)Anchor Boxes---锚框(4)Dimens…

k8s学习-Deployment

Kubernetes通过各种Controller来管理Pod的生命周期 。 为了满足不同业 务 景 , Kubernetes 开发了Deployment、ReplicaSet、DaemonSet、StatefuleSet、Job等多种Controller。我们⾸先学习最常用Deployment。 1.1 Kubectl命令直接创建 第一种是通过kubectl命令直接…

ROS第 9 课 编写简单的服务端 Server

文章目录 第 9 课 编写简单的服务端 Server1.创建服务器代码2.运行服务器节点 第 9 课 编写简单的服务端 Server 1.创建服务器代码 注意:在创建服务器代码之前,需要先创建工作空间和功能包,具体操作过程可前往目录“第4课 创建工作空间与功能…

蓝桥杯每日一题---基数排序

题目 分析 在实际的比赛过程中很少会自己手写排序,顶多是定义一下排序规则。之所以要练习一下基数排序,是因为在后续学习过程中学到后缀数组时需要自己手写基数排序,那么这里使用的方法也和后缀数组一致,理解这里也便于后缀数组的…

领域特定语言(Domain-Specific Language, DSL)在 Visual Studio 2022中的实验——建立领域模型

一、环境 dotnet --version 8.0.101 Microsoft Visual Studio Enterprise 2022 (64 位) - Current 版本 17.8.4 已安装组件 ComponentLinkVisual Studiohttp://go.microsoft.com/fwlink/?LinkId185579Visual Studio SDKhttps://go.microsoft.com/fwlink/?li…

RTC讲解

RTC(Real Time Clock)实时时钟 RTC实时时钟本质上是一个独立的定时器。RTC模块拥有一组连续计数的32位无符号计数器,在相应软件配置下,可提供时钟日历的功能。修改计数器的值可以重新设置系统当前的时间和日期。 RTC模块和时钟配…

提升开发效率,Fiddler Everywhere for Mac助您解决网络调试难题

在现代软件开发中,网络调试是一个不可或缺的环节。无论是前端开发还是后端开发,我们经常需要对网络请求进行监控和调试,以便及时发现并解决问题。而Fiddler Everywhere for Mac作为一款强大的网络调试工具,能够帮助开发者提升工作…

Ubuntu重启后进入initramfs导致无法开机

今晚,我的电脑意外关机,重新开机后打开了虚拟机后出现initramfs,一直无法开机。该虚拟机使用的是 vm17,系统是ubuntu20, 解决方案 使用如下命令查看和识别磁盘、分区或文件系统的信息 在initramfs后面输入 fsck /dev/sdb4 ,即修复上面损坏的…

32 选择组件

效果演示 实现了一个复选框的动画效果,当复选框被选中时,复选框的前面会出现一个勾号,同时复选框的背景颜色会变成灰色,复选框旁边会出现一个火花效果。当复选框被取消选中时,复选框的勾号会消失,复选框的背…

线程同步--生产者消费者模型

文章目录 一.条件变量pthread线程库提供的条件变量操作 二.生产者消费者模型生产者消费者模型的高效性基于环形队列实现生产者消费者模型中的数据容器 一.条件变量 条件变量是线程间共享的全局变量,线程间可以通过条件变量进行同步控制条件变量的使用必须依赖于互斥锁以确保线…

Docker(三)使用 Docker 镜像

作者主页: 正函数的个人主页 文章收录专栏: Docker 欢迎大家点赞 👍 收藏 ⭐ 加关注哦! 使用 Docker 镜像 在之前的介绍中,我们知道镜像是 Docker 的三大组件之一。 Docker 运行容器前需要本地存在对应的镜像&#x…

行驶证OCR识别应用领域有哪些?

随着科技的不断发展,OCR技术已经逐渐成熟,并在各个领域得到了广泛的应用。其中,OCR技术在行驶证识别领域的应用也日益受到关注。本文将重点介绍行驶证OCR识别的应用领域,以便更好地了解这一技术的应用前景。 首先,行驶…

尚硅谷Nginx高级配置笔记

写在前面:本笔记是学习尚硅谷nginx可成的时候的笔记,不是原创,如有需要,可以去官网看视频,以下是pdf文件 Nginx高级 第一部分:扩容 通过扩容提升整体吞吐量 1.单机垂直扩容:硬件资源增加 云…

计算机毕业设计----SSH会议室管理系统

项目介绍 本系统为基于jspsshmysql的会议室管理系统,包含普通用户和管理员,系统功能如下: 普通用户:会议室管理、会议管理、用户管理、个人资料。 管理员用户:会议室管理、会议管理、用户管理、部门管理、设备管理、个…

基于docker创建nginx容器

docker一键安装可以参考我这个博客:一键安装docker 1.创建基础容器 docker run -p280:280 --name nginx -d nginx创建挂载到容器的宿主机文件夹 mkdir -p /home/000nginx-ebrms-ftp/html mkdir -p /home/000nginx-ebrms-ftp/logs mkdir -p /home/000nginx-ebrms-f…

三坐标平台对环境的温度有要求吗——河北北重

三坐标铸铁平台对环境的温度有一定的要求。通常情况下,三坐标平台在使用过程中要求环境的温度保持在一定范围内,以确保测量数据的准确性和稳定性。 具体的温度要求可能会因不同的三坐标铸铁平台型号和制造商而有所不同,一般来说,常…

Unity Mirror VR联机开发 实战篇(二)

一、迁移示例中的联机物体 1、将MirrorExamplesVR工程中的部分文件夹复制到自己的工程中。 1、打开MirrorExamplesVR中的 SceneVR-Common场景。 2、将场景中没用的东西都删掉,只留下面这些,新建一个空物体XR Mirror,将所有剩下的物体拖成XR …