Hi,运维,你懂Java吗--No.9:线程池

        作为运维,你不一定要会写Java代码,但是一定要懂Java在生产跑起来之后的各种机制。

        本文为《Hi,运维,你懂Java吗》系列文章 第九篇,敬请关注后续系列文章

        欢迎关注 龙叔运维(公众号) 持续分享运维经验

前言

        本篇对java的线程池进行讲解,线程池对java应用的性能来说有很重要的影响。

1、什么是线程池

        类似数据库连接池,主要是为了避免线程不断创建销魂造成的大量资源消耗。

        线程池按照设定管理线程。控制运行的线程的数量,将任务放入队列,然后在线程创建后启动这些任务,如果线程数量超过了最大数量超出数量的线程排队等候,等其它线程执行完毕, 再从队列中取出任务来执行。主要特点为:线程复用;控制最大并发数;管理线程。

【线程池的处理流程】

 

如上图,有几个概念,下面进行简单讲解:

a、核心线程:核心线程是在空闲时也不会被回收的线程,可以说是常驻线程,数量由corePoolSize参数控制

b、非核心线程:当核心线程都在处理任务,阻塞队列也满了的情况下,有任务进来,当前线程数没有达到maximumPoolSize参数设置的最大值的时候,就会创建新的线程处理队列中的任务,这些非核心线程不是常驻的,空闲时间超过keepAliveTime 参数设置的时间(时间单位由unit 参数设置)就会被回收

c、阻塞队列/工作队列:核心线程数满之后,新进入的任务加入到队列中等待被执行,队列也有四种,由workQueue参数设置,下面会单独讲解

d、拒绝策略:当阻塞队列满,且线程数已达到最大线程数限制,就会执行拒绝策略,拒绝策略也有四种,由handler参数设置,下面会单独讲解

2、线程池配置

创建线程池的时候一共有7个参数:

a、corePoolSize:核心线程数

b、maximumPoolSize:最大线程数

c、keepAliveTime:非核心线程的最大空闲时间(为0表示非核心线程空闲就立即回收),只有当线程池中的线程数大于corePoolSize时keepAliveTime才会起作用,直到线程中的线程数不大于corepoolSIze。

d、unit:时间单位,作用于keepAliveTime,

e、threadFactory:线程工厂,可以设置线程名,是否为守护线程等

f、workQueue:阻塞队列

g、handler:拒绝策略

 

如下为线程池创建代码:

public ExecutorService executorService(){
    return new ThreadPoolExecutor(
            POLLER_THREAD_COUNT,
            POLLER_THREAD_COUNT * 8,
            10L,
            TimeUnit.SECONDS,
            new ArrayBlockingQueue<>(64),
            new ThreadFactoryBuilder().setNameFormat("AppName_FutureTask-%d").setDaemon(true).build(),
            new ThreadPoolExecutor.CallerRunsPolicy());
}

3、线程池状态

(1)RUNNING:线程池创建之后的初始状态,这种状态下可以执行任务。

(2)SHUTDOWN:该状态下线程池不再接受新任务,但是会将工作队列中的任务执行完毕。

(3)STOP:该状态下线程池不再接受新任务,也不会处理工作队列中的剩余任务,并且将会中断所有工作线程。

(4)TIDYING:该状态下所有任务都已终止或者处理完成,将会执行terminated()钩子方法。

(5)TERMINATED:执行完terminated()钩子方法之后的状态。terminated钩子方法在Executor终止时调用,默认实现不执行任何操作
 

 

4、常见线程池

线程池描述corePoolSizemaximumPoolSizekeepAliveTime阻塞队列
FixedThreadPool创建指定数量线程,且线程一直存在,阻塞队列很大创建时传参和corePoolSize一样0

无界队列

LinkedBlockingQueue

CachedThreadPool没有常驻线程,根据需要增加和减少,使用无容量的同步阻塞队列0Integer.MAX_VALUE60秒

同步队列

SynchronousQueue

ScheduledThreadPool该线程池用于执行定时任务和周期性任务。可以指定线程池中的线程数量。创建时传参Integer.MAX_VALUE0

无界队列(延迟、排序)

DelayedWorkQueue

SingleThreadExecutor该线程池只会创建一个线程,用于执行所有的任务。110

无界队列

LinkedBlockingQueue

SingleThreadScheduledExecutor一个可以周期性执行任务的单线程线程池1Integer.MAX_VALUE0

无界队列(延迟、排序)

DelayedWorkQueue

5、阻塞队列

常用阻塞队列有四种,应该根据业务场景选择合适的

a、ArrayBlockingQueue

一个由数组支持的有界阻塞队列。此队列按 FIFO(先进先出)原则对元素进行排序。创建其对象必须明确大小,像数组一样。

b、LinkedBlockingQueue

一个可改变大小的阻塞队列。此队列按 FIFO(先进先出)原则对元素进行排序。创建其对象如果没有明确大小,默认值是Integer.MAX_VALUE。链接队列的吞吐量通常要高于基于数组的队列,但是在大多数并发应用程序中,其可预知的性能要低。 

Integer.MAX_VALUE表示:int 数据类型的最大值,即:2147483647

c、PriorityBlockingQueue

类似于LinkedBlockingQueue,但其所含对象的排序不是FIFO,而是依据对象的自然排序顺序或者是构造函数所带的Comparator决定的顺序。

d、SynchronousQueue

同步队列。同步队列没有任何容量,往队列中插入数据之后,不能立即返回,必须等待另一个线程将数据处理掉,才会返回,相当于将放入数据到队列的这个线程阻塞住了。

这个使用场景是比较少的,使用SynchronousQueue阻塞队列一般要求maximumPoolSizes为无界,避免线程拒绝执行操作。

 

e、DelayQueue

具有延迟的功能,我们可以设定在队列中的任务延迟多久之后执行。它是无界队列,但是放入的元素必须实现Delayed接口,而Delayed接口又继承了Comparable接口,所以自然就拥有了比较和排序的能力.

6、拒绝策略

线程数已经达到最大线程数,阻塞队列也满了,就会执行拒绝策略,java有下面四个策略,当然也可以自定义策略

  • AbortPolicy:直接抛出 RejectedExecutionException 异常,影响系统运行
  • CallerRunsPolicy:用调用者所在线程(提交任务的线程)来执行任务
  • DiscardOldestPolicy:丢弃任务队列里最早的任务,把提交的任务加入任务队列
  • DiscardPolicy:直接丢弃提交的任务。【如果允许丢弃任务,这就是最好的处理方式】

7、线程池常见异常

7.1、线程池过载

     线程池过载是指线程数量过多造成服务器资源使用过高,降低系统性能

    1、系统性能下降

    2、服务器内存过高,深圳OOM

异常分析:

    1、任务对象过多:线程数达到最大线程数限制,阻塞队列使用的是无界队列,并发持续很高的情况下,线程处理不过来,队列不断新增任务,导致内存撑爆

    2、线程过多,线程数无限制(最大限制为Integer.MAX_VALUE),高并发任务情况下,不断创建线程处理任务,增加服务器资源消耗,如内存,线程栈不断增多,撑爆内存

异常处理:

    1、重启快速恢复(但可能很快继续异常)

    2、使用核实的阻塞队列,设置核实的线程数最大限制,使用合理的拒绝策略

7.2、线程池阻塞

   线程池阻塞是指当线程池中的线程数量达到最大值时,新的任务会被阻塞,导致程序性能下降

    java.util.concurrent.RejectedExecutionException

异常分析:

    一般触发这个报错的时候,就是线程已经达到最大线程限制,且阻塞队列已满,新的任务无法处理

异常处理:

    1、使用合理的拒绝策略,如果是可以忽略的任务,使用丢弃方式是最好的

    2、调整阻塞队列大小,但是要适当,避免过高并发不断创建任务到队列导致内存OOM。

    3、根据业务情况,如果可以异步提交,可以创建任务后就返回,不阻塞提交任务的线程

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

VectorDBBench向量数据库性能评测工具

目录 一、背景和意义 二、特点和优势 三、应用场景和实际效果 四、总结 摘要: VectorDBBench.com是一个基于云计算的向量数据库基准测试平台,旨在评估不同向量数据库的性能和可扩展性。本文介绍了VectorDBBench的背景和意义,分析了VectorDBBench的特点和优势,并从多个方…

Java个人博客系统--基于Springboot的设计与实现

目录 一、项目概述 应用技术 接口实现&#xff1a; 数据库定义&#xff1a; 数据库建表&#xff1a; 博客表数据库相关操作&#xff1a; 添加项⽬公共模块 加密MD5 页面展示&#xff1a;http://121.41.168.121:8080/blog_login.html 项目源码&#xff1a;https://gitee…

selenium 和 chromedriver 使用的一些总结

1 selenium 下载地址 selenium PyPIhttps://pypi.org/project/selenium/ 2 chromedriver 下载地址 &#xff0c;可以下载最新版的 chromedriver ChromeDriver - WebDriver for Chrome - Downloadshttps://chromedriver.chromium.org/downloadsChrome for Testing availabi…

Android 刷新与显示

目录 屏幕显示原理&#xff1a; 显示刷新的过程 VSYNC机制具体实现 小结&#xff1a; 屏幕显示原理&#xff1a; 过程描述&#xff1a; 应用向系统服务申请buffer 系统服务返回一个buffer给应用 应用开始绘制&#xff0c;绘制完成就提交buffer&#xff0c;系统服务把buffer数据…

Redis实战(5)——Redis实现消息队列

消息队列&#xff0c;顾名思义&#xff0c;就是一个存放消息的队列。最简单的消息队列包含3个角色 生产者&#xff1a;将消息存入队列中队列&#xff1a;存放和管理消息消费者&#xff1a; 将消息从队列中取出来并做业务处理 R e d i s 提供了三种实现消息队列的方式&#x…

Linux性能学习(4.5):网络_TCP四次挥手内核参数优化

文章目录 1 四次挥手2 参数优化2.1 tcp_orphan_retries--->FIN报文重传次数2.2 tcp_max_orphans--->孤儿连接最大数量2.3 tcp_fin_timeout--->FINE_WAIT2状态等待时间2.4 tcp_max_tw_buckets2.5 tcp_tw_reuse--->复用未释放的端口 3 总结 参考资料&#xff1a; 1. …

星图按转化线索回传对接思路与示例

一、什么是星图&#xff1f;二、什么是线索转化&#xff1f;三、对接中的一些疑问&#xff1f;四、如何对接开发&#xff1f;五、星图侧如何联调测试&#xff1f; 一、什么是星图&#xff1f; 抖音星图是抖音电商蓝图下&#xff0c;为品牌方、MCN公司和明星/达人服务并收取分…

【DFS】17. 电话号码的字母组合

【DFS】17. 电话号码的字母组合 Halo&#xff0c;这里是Ppeua。平时主要更新C语言&#xff0c;C&#xff0c;数据结构算法…感兴趣就关注我bua&#xff01; TOC 题目: [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-rikjhVFD-1691333891079)(C:\Us…

IAR开发环境的安装、配置和新建STM32工程模板

IAR到环境配置到新建工程模板-以STM32为例 一、 简单介绍一下IAR软件1. IAR的安装&#xff08;1&#xff09; 下载IAR集成开发环境安装文件&#xff08;2&#xff09; 安装 2. 软件注册授权 二、IAR上手使用(基于STM32标准库新建工程)1、下载标准库文件2、在IAR新建工程&#x…

华为云交付

文章目录 一、华为云-公有云架构华为公有云的主要服务1.华为云服务—计算类2.华为云服务——存储类3.华为云服务—网络类4.华为云服务—管理和监督类5.华为云数据库 二、待续 一、华为云-公有云架构 华为公有云的主要服务 ECS&#xff1a;弹性云服务器&#xff08; Elastic Cl…

交互流程图设计软件都有哪些?

交互流程图是设计行业信息流、观点流或组件流的图形代表。但是市场上应该如何选择各种交互流程图软件呢&#xff1f;如何使用高质量的交互流程图软件来绘制高端氛围的高档流程图&#xff1f;今天&#xff0c;小边给您带来了十个超级实用的交互流程图软件&#xff0c;我希望能帮…

解决宝塔面板升级获取更新包失败,请稍后更新或联系宝塔运维

宝塔Linux面板执行升级命令后失败&#xff0c;提示“获取更新包失败&#xff0c;请稍后更新或联系宝塔运维”如何解决&#xff1f;新手站长分享宝塔面板升级失败的解决方法&#xff1a; 宝塔面板升级失败解决方法 1、使用root账户登录到你的云服务器上&#xff0c;宝塔Linux面…

亿欧智库:2023中国宠物行业新趋势洞察报告(附下载)

关于报告的所有内容&#xff0c;公众【营销人星球】获取下载查看 核心观点 户外赛道本质上迎合了全球共性需求的增长&#xff0c;从养宠意愿的转化到养宠生活的需求&#xff0c;多层次的需求推动行业发展新趋势 从需求端进行分析&#xff0c;可以将养宠意愿的转化分为三个层…

Python语法:... for ... in ... if ...

Python中&#xff0c;for...in...[if]...语句是一种简洁的构建List的方法&#xff0c;从for给定的List中选择出满足if条件的元素组成新的List&#xff0c;其中if是可以省略的。下面举几个简单的例子进行说明 [for in ]: ...for ....in..... 语句. 实例如下&#xff1a; (1) …

零知识证明技术概述

简述 隐私泄露问题给企业带来了巨大的损失&#xff0c;本文简述零知识证明技术并且给出对应的应用示例&#xff1a; 什么是零知识证明&#xff1f; 零知识证明又被称为零知识协议&#xff0c;利用数学知识在双方不需要直接传递信息本身的前提下来验证信息的正确性。这个思想…

LLM reasoners 入门实验 24点游戏

LLM reasoners Ber666/llm-reasoners 实验过程 实验样例24games&#xff0c;examples/tot_game24&#xff0c;在inference.py中配置使用代理和open ai的api key。 首先安装依赖 git clone https://github.com/Ber666/llm-reasoners cd llm-reasoners pip install -e .然后…

【JAVA】继承

作者主页&#xff1a;paper jie的博客 本文作者&#xff1a;大家好&#xff0c;我是paper jie&#xff0c;感谢你阅读本文&#xff0c;欢迎一建三连哦。 本文录入于《JAVASE语法系列》专栏&#xff0c;本专栏是针对于大学生&#xff0c;编程小白精心打造的。笔者用重金(时间和精…

437. 路径总和 III

题目描述&#xff1a; 主要思路&#xff1a; 方法一&#xff1a;递归 从每个节点开始一次递归 class Solution { public:int ans0;void dfs(TreeNode* now,int targetSum, long sum){if(!now)return;sumnow->val;if(sumtargetSum)ans1;dfs(now->left,targetSum,sum);df…

[Docker实现测试部署CI/CD----构建成功后钉钉告警(7)]

目录 15、钉钉告警创建项目群&#xff0c;然后添加机器人添加机器人Jenkins 系统配置项目配置修改Jenkinsfile文件&#xff0c;添加钉钉提示信息测试 不修改Jenkinsfile文件&#xff0c;添加钉钉提示信息测试 15、钉钉告警 创建项目群&#xff0c;然后添加机器人 首先需要在钉…

Grafana制作图表-自定义Flink监控图表

简要 有时候我们在官网的Grafana下载的图表是这样的&#xff0c;如下图 #算子的处理时间&#xff0c;就是处理数据的延迟数据抓取&#xff0c;这个的说明看下下面的文章 metrics.latency.interval: 60 metrics.reporter.promgateway.class: org.apache.flink.metrics.prometh…