关于线程池,它的扩展问题你知道吗?(自己总结)

专门想一下为什么线程池不用Excutors,之前的印象是错的,居然还拿来面试里讲,惭愧,这里暂时整理俩小问题,其他的后续可能会更新。。

线程池是创建的越大越好嘛

#线程池创建的越大越好吗

Tip:2024-04-10 更新

不是。
刚开始想着,线程池创建的大,请求来到不是刚好能分配线程执行这个请求嘛,不是挺好,为什么会导致效率更低呢?

其实不是,如果线程池创建太大,也就是说可用的线程很多,但是 CPU 的核数有限啊,线程执行需要调用 CPU ,所以多线程之间需要争夺 CPU 的执行权,这个过程中可能会发生频繁的上下文切换,导致效率更低

并且呢,线程创建的多,也会消耗更多的内存空间给线程。所以可以根据上面的公式,设置好合理的线程参数,来最大程度的利用线程池。

那问题来啦,线程池创建的太小呢?

  1. 线程池创建太小,可能会导致任务来到的速度大于处理的速度,最终都堆积在任务队列中。假如使用的是无界的任务队列(比如 java 内置的 Executor 类的线程池),那就会导致 OOM 问题。
  2. 像 ThreadPoolExecutor 的线程池,它的任务队列是有限大小的,而且有相应的拒绝策略可以配置,更好的管理,防止 OOM 等问题。

如果是你,你会选用 Excutors 还是 ThreadPoolExecutor ,为什么?

这个面试会问到。

怎么选用得看它们的特性是什么,比如下面这点:

  1. 线程池的用途不同

Excutors 类内部提供了很多静态方法,可以直接快速定义一些种类的简单线程池,比如 FixedThreadPool、cachedThreadPool 等的快捷创建方法。
如图:
在这里插入图片描述

再具体看其中一个方法:
在这里插入图片描述

可以看到这些静态方法,只是把 ThreadPoolExecutor 的参数改成了默认值,所以其底层也是用到了 ThreadPoolExecutor ,它们之间并不是完全不同的两个东西

所以 Excutors 并不是之前想的,什么无界队列导致 OOM 溢出问题才不能用,而是因为这种方式生成的线程池不够"个性化",也就是不能满足一些复杂的需求

  • 至于 OOM 问题,那是因为一些线程池的特性,比如 SingleThreadPool 单线程池,它的任务队列真是无界的,所以真会溢出
  • 还有 CachedThreadPool ,它是基于内存的,所以不管你请求来多少,只要没有空闲线程它就会新创建线程来处理新请求,虽然这种场景确实存在,但是你的服务器不一定能撑得住啊

最后,ThreadPoolExecutor 为什么优先用知道了吧,参数你自己定,更加的可控,自己指定线程创建工厂和任务队列,以及核心线程、最大线程等。

至于线程池参数怎么定那就是其他内容了,之前有整理过,不多说,解耦一下。


补充线程池参数配置:

合理设置线程池参数

我们调整线程池中的线程数量的最主要的目的是为了充分并合理地使用 CPU 和内存等资源,从而最大限度地提高程序的性能。在实际工作中,我们需要根据任务类型的不同选择对应的策略。

主要对于两种批量任务有不同的设置方法,最后会有一个公式:

  1. CPU 密集型任务

也就是大量需要进行计算、加密、解密等耗费 CPU 资源的任务。如果线程池的线程数量太多,会导致这些任务争夺 CPU 执行权,频繁的进行上下文切换,这个效率会降低。

所以一般设置线程数为 CPU 核数的 1 到 2 倍,我的项目里设置的是当前可用 CPU 核数的 1.5 倍。(最大线程数是 2 倍)

  1. IO 密集型任务

也就是需要进行文件读写,数据库读写等任务,不会耗费太多 CPU 资源,但是 CPU 会太闲,你闲下来不就是浪费资源了吗,反正机器不用休息(doge)

这种你就可以多开一些线程,在执行 IO 任务的时候,CPU 不用等待 IO 任务结束,而是先去执行一些需要 CPU 的操作,所以要多开线程,去调用 CPU,尽可能的提高 CPU 利用率

  1. 通用计算公式

java 并发编程里有这个公式:线程数 = CPU 核心数 *(1+平均等待时间/平均工作时间)

其实也对应两种类型的任务,比如平均等待时间长,就是 IO 密集型任务,要多开线程提高 CPU 利用率。相反,工作时间长就是 CPU 密集型,需要适量设置线程数。

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

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

相关文章

本地搭建hydra服务用go以验证oidc流程

目录 1、docker搭建hydra,环境配置: 2、搭建完成后服务调用: 2.1保证服务正常启动: 2.2 通过postman调用,获取client_id: 2.3 通过client_id,实现oauth2/auth调用 3. 通过go语言实现oidc验…

【qt】容器的用法

容器目录 一.QVertor1.应用场景2.增加数据3.删除数据4.修改数据5.查询数据6.是否包含7.数据个数8.交换数据9.移动数据10.嵌套使用 二.QList1.应用场景2.QStringList 三.QLinkedList1.应用场景2.特殊点3.用迭代器来变量 四.QStack1.应用场景2.基本用法 五.QQueue1.应用场景2.基本…

【前端每日一题】day2

用JS写一个快速排序算法 function quickSort(arr) {if (arr.length < 1) {return arr;}const pivot arr[Math.floor(arr.length / 2)];const left [];const right [];for (let i 0; i < arr.length; i) {if (i Math.floor(arr.length / 2)) {continue; // Skip piv…

OS复习笔记ch5-3

引言 上一节我们学习了关于信号量机制的一些内容&#xff0c;包括信号量的含义&#xff0c;对应的PV操作等。 如图所示&#xff0c;上一节主要是针对信号量的互斥&#xff0c;其实信号量机制还可以做很多事情&#xff0c;比如实现进程同步和前驱关系&#xff0c;这一节我们先复…

【Spring】JdbcTemplate

JdbcTemplate 是 Spring 提供的一个 JDBC 模板类&#xff0c;是对 JDBC 的封装&#xff0c;简化 JDBC 代码 也可以让 Spring 集成其它的 ORM 框架&#xff0c;例如&#xff1a;MyBatis、Hibernate 等 使用 JdbcTemplate 完成增删改查 一、环境准备 数据库&#xff1a; 准备…

Marin说PCB之如何快速打印输出整板的丝印位号图?

当小编我辛辛苦苦加班加点的把手上的板子做到投板评审状态的时候&#xff0c;坐在我旁边的日本同事龟田小郎君说让我把板子上的丝印也要调一下&#xff0c;我当时就急了&#xff0c;这么大的板子&#xff0c;将近1W多PIN 了都&#xff0c;光调丝印都要老半天啊&#xff0c;而且…

Python基础学习之datetime模块

在Python编程中&#xff0c;处理日期和时间是一个常见的需求。Python的datetime模块提供了丰富的类和方法&#xff0c;用于表示和操作日期、时间、时间间隔等。本文将详细介绍Python的datetime模块&#xff0c;并给出一些实用的示例。 1. datetime模块概览 datetime模块是Pyt…

Docx文件误删除如何恢复?别再花冤枉钱了,4个高效恢复软件!

不管是工作还是学习&#xff0c;总是会与各种各样的文件打交道。文件量越多就越容易出现文件丢失、文件误删的情况。遇到这些情况&#xff0c;失去的文件还能找回来吗&#xff1f;只要掌握了一些数据恢复方法&#xff0c;是很有机会恢复回来的&#xff0c;下面我会将这些方法分…

[机器学习系列]深入探索回归决策树:从参数选择到模型可视化

目录 一、回归决策树的参数 二、准备数据 三、构建回归决策树 (一)拟合模型 (二)预测数据 (三)查看特征重要性 (四)查看模型拟合效果 (五) 可视化回归决策树真实值和预测值 (六)可视化决策树并保存 部分结果如下&#xff1a; 一、回归决策树的参数 DecisionTreeRegress…

zookeeper之分布式环境搭建

ZooKeeper的分布式环境搭建是一个涉及多个步骤的过程&#xff0c;主要包括准备工作、安装ZooKeeper、配置集群、启动服务以及验证集群状态。以下是搭建ZooKeeper分布式环境的基本步骤&#xff1a; 1. 准备工作 确保所有节点的系统时间同步。确保所有节点之间网络互通&#xf…

Redis-5 分布式锁

一.为什么要使用分布式锁&#xff1f; 传统的互斥锁synchronized只能作用于同一台虚拟机上的线程&#xff0c;在使用服务器集群部署的情况下&#xff0c;互斥锁就会失效&#xff0c;因此要采用分布式锁来处理不同服务器上的线程访问同一资源的情况。 二.redis的分布式锁是如何…

NVIDIA_SMI has failed because it couldn’t communicate with the NVIDIA driver

参考&#xff1a;https://www.zhihu.com/question/474222642/answer/3127013936 https://blog.csdn.net/ZhouDevin/article/details/128265656 nvidia-smi查看报错&#xff0c;nvcc正常 1&#xff09;查看nvidia版本 ls /usr/src | grep nvidia nvidia-550.78 2&#xff09;…

暗区突围国际服pc端怎么获取测试资格 twitch掉落资格获取教程

《暗区突围》是由腾讯魔方工作室群开发的第一人称射击类手游。游戏以从暗区撤离并收集物资满载而归作为最终目的&#xff0c;带出的战利品可以存储在仓库中&#xff0c;又可以出售用以换取游戏金钱。游戏中玩家可以创建男性或女性角色&#xff0c;可以通过选择脸型、发型、发色…

冒泡法排序方法与找到出现最多的字符及出现次数

一. 简介 本文学习一下&#xff0c;字符大小排序&#xff0c;获取最大值与最小值。 输出字符串中出现最多的字符&#xff0c;以及出现次数。 二. 冒泡法排序方法与获取最大最小值 1. 冒泡法排序 终端随机输入一个字符串&#xff0c;只包括字符0-9&#xff0c;字符串长度…

2024-05-08 postgres-查询树Query-分析

摘要: pg的词法分析和语法分析使用的技术与mysql相同&#xff0c;此法分析使用bison&#xff0c;语法分析使用了flex。之后ANSI SQL句子被转换为查询树。 Query 结构体保存了文本类型的 SQL,经过语法分析后的分析结果&#xff0c;Query 结构体的成员与 SOL语句的各个子句基本…

AI中LangChain实现RAG中的pdf原理以及快速上手

AI中LangChain实现RAG中的pdf原理以及快速上手 什么是LangChain LangChain是一种基于自然语言处理技术的语言生成模型&#xff0c;它可以将输入的文本转换为自然语言的输出。LangChain的实现原理是基于RAG&#xff08;Retriever-Reader-Generator&#xff09;模型&#xff0c…

C++ 动态内存管理

例如&#xff1a;动态内存和释放单个数据的存储区 一 用new运算符初始化单个数据的存储区 举例

Qt:实现git中diff的功能

在 Git 中&#xff0c;有四种 diff 算法&#xff0c;即 Myers、Minimal、Patience 和 Histogram&#xff0c;用于获取位于两个不同 commit 中的两个相同文件的差异。 Myers算法实现参考&#xff1a; Myers‘Diff之贪婪算法_myers算法-CSDN博客 Git Diff 算法详解&#xff1a…

深度学习算法集成部署

文章目录 0 Docker容器部署1 制作dockerfile2 新建镜像3 新建容器4 运行脚本5 异常处理0 Docker容器部署 使用 Docker 容器部署深度学习模型有以下几个主要优势: 环境一致性:Docker 容器可以将应用程序及其所需的依赖项打包在一起,确保应用程序在不同环境中的运行一致性。这对…

为什么在二三十岁时应该努力变强大?

一、对于即将三十岁或三十岁的人的建议&#xff0c;包括举重、跑步、学习等健身技能&#xff0c;以及在生活中如何处理困难和挑战。 举重是二三十岁的人的最佳做法之一 学习如何在身体上、感情上和精神上挑战极限 在城市里寻找机会&#xff0c;接受邀请&#xff0c;强迫自己出去…