【面试实战】# 并发编程之线程池配置实战

1.先了解线程池的几个参数含义

corePoolSize (核心线程池大小):

  • 作用: 指定了线程池维护的核心线程数量,即使这些线程处于空闲状态,它们也不会被回收。
  • 用途: 核心线程用于处理长期的任务,保持最低的线程数量,以减少线程的创建和销毁的开销。

maximumPoolSize (最大线程池大小):

  • 作用: 指定了线程池中允许的最大线程数。超过这个数量的线程将不会被创建。
  • 用途: 限制了线程池的大小,以防止资源耗尽。

keepAliveTime (线程空闲时间):

  • 作用: 当线程数超过 corePoolSize 时,多余的线程在空闲时间超过指定时间后将会被终止和回收。
  • 用途: 用于回收不再需要的线程,降低资源消耗。只对超过 corePoolSize 的线程起作用。

unit (时间单位):

  • 作用: 与 keepAliveTime 一起使用,指定线程空闲时间的时间单位(如秒、毫秒)。
  • 用途: 定义 keepAliveTime 的时间单位。

workQueue (任务队列):

  • 作用: 用于保存等待执行的任务的队列。

  • 用途

    : 管理任务的排队和处理方式,不同的队列类型可以影响线程池的行为。

    • 常见的队列类型有:
      • SynchronousQueue: 不存储任务,任务直接交给线程执行。如果没有空闲线程,则创建新线程。
      • LinkedBlockingQueue: 无界队列,可以存储任意多的任务。只有在任务队列为空时,才会创建新线程。
      • ArrayBlockingQueue: 有界队列,存储固定数量的任务,当队列满时,任务将被拒绝。

threadFactory (线程工厂):

  • 作用: 用于创建线程的工厂,可以定制线程的创建,比如设置线程名、优先级等。
  • 用途: 统一管理线程的创建细节,有助于调试和监控。

handler (饱和策略/拒绝策略):

  • 作用: 当任务无法提交给线程池(例如线程池已满且任务队列已满)时,如何处理新任务。

  • 用途

    : 定义任务无法被执行时的处理方式。

    • 常见策略有:
      • AbortPolicy: 抛出 RejectedExecutionException 异常。
      • CallerRunsPolicy: 由调用者线程执行该任务。
      • DiscardPolicy: 丢弃新提交的任务。
      • DiscardOldestPolicy: 丢弃队列中最旧的任务。

2.调整线程池配置应对高并发(常规操作)

为了应对高并发的需求,可以考虑以下调整:

  1. 增大 corePoolSizemaximumPoolSize:
    • 增加核心线程和最大线程数可以提高线程池的并发处理能力,减少任务的等待时间。
  2. 调整 keepAliveTimeunit:
    • 减少 keepAliveTime 可以更快地回收闲置线程,释放资源。相反,增加 keepAliveTime 适用于任务间隔较长的场景,以避免频繁创建和销毁线程。
  3. 选择合适的 workQueue:
    • 使用 SynchronousQueue 可以在任务很多但线程数不足时迅速增加线程数。
    • 使用 LinkedBlockingQueue 可以应对任务队列过长的问题,但可能导致线程数不会增加到最大。
    • 使用 ArrayBlockingQueue 适合在任务数有限的场景,防止资源耗尽。
  4. 合理配置 handler:
    • 根据系统需求选择适合的拒绝策略。比如,在希望任务尽量被处理时使用 CallerRunsPolicy,在任务不能丢失时选择 AbortPolicy
  5. 优化 threadFactory:
    • 使用自定义的线程工厂设置线程名、优先级、守护线程等,提高线程管理的清晰度和系统稳定性。
  6. 监控和调整:
    • 定期监控线程池的性能指标,如任务队列长度、线程使用率等,并根据实际情况动态调整参数配置。
// 创建线程池
ThreadPoolExecutor executor = new ThreadPoolExecutor(10,                   // corePoolSize50,                   // maximumPoolSize60,                   // keepAliveTimeTimeUnit.SECONDS,     // keepAliveTime's unitnew LinkedBlockingQueue<>(100), // workQueueExecutors.defaultThreadFactory(), // threadFactorynew ThreadPoolExecutor.AbortPolicy() // handler
);// 提交任务
executor.submit(() -> {// Task implementation
});// 关闭线程池
executor.shutdown();

3.IO密集型、CPU密集型任务的合理配置(生产常用)

3.1 IO密集型任务

IO密集型任务:(例如网络操作、文件读写)通常不需要大量的CPU时间,但可能会等待IO操作的完成。为了有效利用系统资源,可以配置更多的线程来掩盖IO操作的等待时间。

配置建议:

  • corePoolSizemaximumPoolSize:
    • 建议的线程数通常远超过 CPU 核心数,因为线程在等待IO操作时不会占用CPU。可以使用 (CPU 核心数 * 2) 或更多,甚至是 (CPU 核心数 * 2) + 1 这种经验值。
    • 如果线程数太少,CPU资源可能未能充分利用。太多的线程可能会导致线程上下文切换的开销。
  • keepAliveTimeunit:
    • 适当地增加 keepAliveTime,让线程在空闲时保留一段时间,以便在短时间内有任务到达时无需重新创建线程。
  • workQueue:
    • LinkedBlockingQueue 是常见选择,因为它可以有效处理大量任务,而不需要频繁地创建和销毁线程。
    • SynchronousQueue 也可以用于高并发IO场景,确保任务直接交给线程执行,迅速响应。

示例:

int numCores = Runtime.getRuntime().availableProcessors();
ThreadPoolExecutor ioBoundExecutor = new ThreadPoolExecutor(numCores * 2,                // corePoolSizenumCores * 2 + 1,            // maximumPoolSize60L,                         // keepAliveTimeTimeUnit.SECONDS,            // keepAliveTime's unitnew LinkedBlockingQueue<>(), // workQueueExecutors.defaultThreadFactory(), // threadFactorynew ThreadPoolExecutor.CallerRunsPolicy() // handler
);

3.2 CPU密集型任务

CPU密集型任务:(例如计算密集的操作、数据处理)主要消耗CPU 资源,因此线程数应该与 CPU 核心数相匹配,以避免过度的线程上下文切换和资源竞争。

配置建议:

  • corePoolSizemaximumPoolSize:
    • 通常设置为 CPU 核心数CPU 核心数 + 1
    • 过多的线程可能导致频繁的上下文切换,降低性能。
  • keepAliveTimeunit:
    • keepAliveTime 通常设置较短,适合及时回收空闲线程。
  • workQueue:
    • SynchronousQueueArrayBlockingQueue 是不错的选择,可以避免任务堆积,确保线程数控制在合理范围内。

示例:

int numCores = Runtime.getRuntime().availableProcessors();
ThreadPoolExecutor cpuBoundExecutor = new ThreadPoolExecutor(numCores,                    // corePoolSizenumCores + 1,                // maximumPoolSize30L,                         // keepAliveTimeTimeUnit.SECONDS,            // keepAliveTime's unitnew SynchronousQueue<>(),    // workQueueExecutors.defaultThreadFactory(), // threadFactorynew ThreadPoolExecutor.AbortPolicy() // handler
);

3.3 关键考虑因素

  1. 系统资源和负载:
    • 监控系统的实际负载和资源使用情况,定期调整配置。
  2. 任务特性:
    • 根据任务的性质(长任务、短任务、IO 密集型、CPU 密集型)选择合适的线程池配置。
  3. 阻塞时间:
    • 对于 IO 密集型任务,理解和分析任务的阻塞时间,并根据其阻塞时间设置合适的线程池大小。
  4. 拒绝策略:
    • 合理选择拒绝策略(如 AbortPolicy, CallerRunsPolicy),确保系统在负载过高时能平稳处理任务。

4.专业级线程池配置(大厂规范)

4.1 线程池大小的计算公式

IO 密集型任务

对于IO密集型任务,可以使用以下公式计算适合的线程池大小:

file

  • N_threads: 推荐的线程池大小
  • N_cores: CPU核心数
  • W: 任务的等待时间(包括IO操作的等待时间)
  • C: 任务的计算时间
  • U: 期望的CPU使用率,通常设为0.8~0.9,避免CPU负载过高(0 < U < 1)

解释: 公式中的 W/C反映了IO操作占用的时间比,1 - U 是为了预留一定的CPU资源。

示例:

假设有一个任务,CPU核心数为8,IO等待时间为200ms,计算时间为100ms,期望的CPU使用率为80%,则推荐的线程池大小为:

file

这意味着你可能需要配置大约120个线程来处理IO密集型任务。

CPU 密集型任务

对于CPU密集型任务,线程池的大小通常可以通过以下公式估算:

file

在CPU密集型场景下,由于 W 很小或接近于零,因此公式通常简化为:

file

示例:

假设有一个任务,CPU核心数为8,计算时间大部分占用时间,等待时间可以忽略不计,则推荐的线程池大小为:

file

5.根据TPS和QPS进行线程池计算(生产常用)

其实和4的公式差不多

5.1 基础概念

  • TPS (Transactions Per Second): 每秒系统处理的事务数量。这通常用于描述系统处理更复杂的业务逻辑的能力。
  • QPS (Queries Per Second): 每秒系统处理的查询数量,通常用于衡量服务端API或数据库的查询处理能力。
  • 响应时间: 单个请求或事务的平均处理时间。

5.2 公式:

file

  • N_threads: 推荐的线程池大小
  • Q: 每秒的请求数(TPS 或 QPS)
  • R: 平均响应时间(秒)
  • U: 系统期望的CPU利用率(< 1, 通常为80%~90%)

解释: 公式描述了在满足特定吞吐量和响应时间的情况下,需要的线程数,预留了一部分CPU资源以防过载。

5.3 IO密集型、CPU密集型任务选择

这里我们主要举例说明IO密集型任务

因为:CPU密集型任务主要消耗CPU资源,线程数接近CPU核心数就足够,可以加一个额外的线程来处理。Nthreads=Ncores+1

IO密集型:

公式:

file

说明: 由于IO密集型任务在等待IO时不会占用CPU,因此线程数可以较高,适用于处理高并发的IO操作。

示例:

假设系统需要处理每秒500个请求(Q = 500),每个请求的平均响应时间为0.2秒,系统期望的CPU利用率为80%(U = 0.8):

file

这意味着你可能需要大约500个线程来处理这些IO密集型请求。

示例代码:

int qps = 500;
double responseTime = 0.2;
double targetUtilization = 0.8;int nThreads = (int) (qps * responseTime / (1 - targetUtilization));ThreadPoolExecutor ioBoundExecutor = new ThreadPoolExecutor(nThreads,                // corePoolSizenThreads,                // maximumPoolSize60L,                     // keepAliveTimeTimeUnit.SECONDS,        // keepAliveTime's unitnew LinkedBlockingQueue<>(), // workQueueExecutors.defaultThreadFactory(), // threadFactorynew ThreadPoolExecutor.CallerRunsPolicy() // handler
);

6.总结

  • IO密集型任务: 使用公式 file 计算线程池大小。
  • CPU密集型任务: 使用公式 file计算线程池大小。
  • 混合型任务: 综合IO和CPU的公式进行计算和调整。
  • file
    • W: 平均等待时间
    • C: 平均计算时间
  • 实际应用: 根据QPS或TPS、响应时间、期望的CPU利用率等参数进行计算,并定期监控系统负载进行调整。

合理的线程池配置可以显著提升系统的处理能力和资源利用率,因此根据具体需求和系统指标进行精细配置是至关重要的。

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

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

相关文章

【Unity拖拽物体】实现对点中的3D物体进行拖拽的功能

场景结构&#xff0c;两个普通模型 第一种 脚本所挂载的物体才可以被拖拽 【PC鼠标版本】 using UnityEngine;// 这个脚本实现了&#xff0c;本脚本所在的游戏物体能够被拖拽 public class DragObjectT : MonoBehaviour {private Vector3 screenPoint; // 存储物体在屏幕上的位…

docker基础使用教程

1.准备工作 例子&#xff1a;工程在docker_test 生成requirements.txt文件命令&#xff1a;&#xff08;使用参考链接2&#xff09; pip list --formatfreeze > requirements.txt 参考链接1&#xff1a; 安装pipreqs可能比较困难 python 项目自动生成环境配置文件require…

【C语言】解决C语言报错:Invalid Pointer

文章目录 简介什么是Invalid PointerInvalid Pointer的常见原因如何检测和调试Invalid Pointer解决Invalid Pointer的最佳实践详细实例解析示例1&#xff1a;未初始化的指针示例2&#xff1a;已释放的指针示例3&#xff1a;返回局部变量的指针示例4&#xff1a;野指针 进一步阅…

5个wordpress成品站主题

Sora索啦高端制造业wordpress主题 红色高端制造业wordpress主题&#xff0c;适合外贸企业出海建独立站的wordpress模板。 https://www.jianzhanpress.com/?p5885 Polar钋啦wordpress外贸主题 制造业wordpress网站模板&#xff0c;适合生产制造企业官方网站使用的wordpress外…

汉语翻译藏语软件,这几款软件不妨一试!

在全球化日益加深的今天&#xff0c;语言障碍成为了许多人在文化交流、商务洽谈或旅游探险中不得不面对的问题。特别是对于汉语和藏语这两种语言来说&#xff0c;由于其独特的文化背景和语法结构&#xff0c;翻译起来更是难上加难。不过&#xff0c;好在科技的进步为我们带来了…

Intelij IDEA中Mapper.xml无法构建到资源目录的问题

问题场景&#xff1a; 在尝试把原本在eclipse上的Java Web项目转移至Intelij idea上时&#xff0c;在配置文件均与eclipse一致的情况下出现了如下报错&#xff1a; org.apache.ibatis.binding.BindingException: Invalid bound statement (not found): cn.umbrella.crm_core.…

图书管理系统(详解版 附源码)

目录 项目分析 实现页面 功能描述 页面预览 准备工作 数据准备 创建数据库 用户表 创建项目 导入前端页面 测试前端页面 后端代码实现 项目公共模块 实体类 公共层 统一结果返回 统一异常处理 业务实现 持久层 用户登录 用户注册 密码加密验证 添加图书…

Mac 安装HomeBrew(亲测成功)

1、终端安装命令&#xff1a; /bin/zsh -c "$(curl -fsSL https://gitee.com/cunkai/HomebrewCN/raw/master/Homebrew.sh)"执行后&#xff0c;没有安装git&#xff0c;会先安装&#xff0c;安装后再执行一下命令。 2、根据中文选择源安装 3、相关命令 查看版本号&a…

本地服务怎么发布成rpc服务

目录 1.引入 2.user.proto 3.userservice.cc 1.引入 example文件夹作为我们框架项目的使用实例&#xff0c;在example文件夹下创建callee和caller两个文件夹 callee是RPC服务的提供者。在callee创建一个文件&#xff1a;userservice.cc 我们有没有这样一个框架&#xff0c;把…

【面试题】MySQL数据库

目录 什么是视图&#xff0c;视图的作用是什么&#xff1f;什么是索引&#xff1f;MySQL中有哪些类型的索引&#xff1f;简述索引设计原则&#xff1f;简述索引的数据结构&#xff1f;简述Hash 和 B 树索引的区别&#xff1f;列出MySQL中导致索引失效的情况&#xff1f;简述数据…

mysql窗口函数排名查询 与 连续出现的数字查询

排名查询 学会这一个查询&#xff0c;我们应该对该类型的查询 方法就能有一个了解&#xff0c;不然 如果下次遇到该类型的查询&#xff0c;我们依然分析不出 给你一张表&#xff0c;里面有id 和score字段&#xff0c;根据score的分数大小 排序 &#xff0c;假如有相同的分数&…

【山东】2024年夏季高考文化成绩一分一段表

文末有图片版&#xff0c;可直接保存下载&#xff01;&#xff01; 2024年夏季高考文化成绩一分一段表分数段全体-选考物理-选考化学-选考生物-选考思想政治-选考历史-选考地理分数段本段人数累计人数本段人数累计人数本段人数累计人数本段人数累计人数本段人数累计人数本段人…

Upload-Labs-Linux1 使用 一句话木马

解题步骤&#xff1a; 1.新建一个php文件&#xff0c;编写内容&#xff1a; <?php eval($_REQUEST[123]) ?> 2.将编写好的php文件上传&#xff0c;但是发现被阻止&#xff0c;网站只能上传图片文件。 3.解决方法&#xff1a; 将php文件改为图片文件&#xff08;例…

毕业生离校系统

摘 要 随着信息技术的快速发展和普及&#xff0c;越来越多的高校开始利用信息化手段来提升管理和服务效率。毕业生离校是高校管理工作中的一个重要环节&#xff0c;涉及到毕业生的个人信息、学业成绩、离校手续等多个方面。传统的离校流程往往繁琐、耗时&#xff0c;且容易出现…

Apple - Framework Programming Guide

本文翻译自&#xff1a;Framework Programming Guide&#xff08;更新日期&#xff1a;2013-09-17 https://developer.apple.com/library/archive/documentation/MacOSX/Conceptual/BPFrameworks/Frameworks.html#//apple_ref/doc/uid/10000183i 文章目录 一、框架编程指南简介…

永洪bi里topN的设置/用法

要实现的效果&#xff1a;实现通过输入参数&#xff0c;进行图表top的排序筛选 图示&#xff1a; 筛选前&#xff1a; 输入3&#xff0c;看top3的值&#xff1a; 输入-3&#xff0c;看倒数3个的值&#xff1a; 设置步骤&#xff1a; 1️⃣&#xff1a;添加一个“文本参数组件…

打造智能家居:用ESP32轻松实现无线控制与环境监测

ESP32是一款集成了Wi-Fi和蓝牙功能的微控制器&#xff0c;广泛应用于物联网项目。它由Espressif Systems公司开发&#xff0c;具有强大的处理能力和丰富的外设接口。下面我们将详细介绍ESP32的基础功能和引脚功能&#xff0c;并通过具体的实例项目展示其应用。 主要功能 双核处…

找不到mfc140u.dll怎么修复,mfc140u.dll丢失的多种修复方法

计算机丢失mfc140u.dll文件会导致依赖该文件的软件无法正常运行。mfc140u.dll是Microsoft Visual C 2015的可再发行组件之一&#xff0c;它属于Microsoft Foundation Class (MFC) 库&#xff0c;许多使用MFC开发的程序需要这个DLL文件来正确执行。丢失了mfc140u.dll文件。会导致…

数据结构需要每个都具体实现吗?

在开始前刚好我有一些资料&#xff0c;是我根据网友给的问题精心整理了一份「数据结构的资料从专业入门到高级教程」&#xff0c; 点个关注在评论区回复“666”之后私信回复“666”&#xff0c;全部无偿共享给大家&#xff01;&#xff01;&#xff01;用c的stl能刷算法题是不…

水浅王八多

今天有三个被自媒体和韭菜们转疯的视频。 &#xff08;1&#xff09; 财政部公布&#xff1a;今年1-5月份证券交易印花税&#xff0c;同比去年1-5月份&#xff0c;降低50.8%。 其实是&#xff1a;2023年8月27日&#xff0c;为活跃资本市场&#xff0c;财政部、证监会和三大交易…