线程池相关知识

news2024/12/25 4:41:23
  1. 什么是线程池?

    • 线程池是一种管理线程的机制,提前创建好一定数量的线程放在池中。
    • 当有任务需要执行时,从线程池中取出线程执行任务;任务执行完后,线程不会消失,而是返回到线程池中,等待下一个任务。
  2. 为什么要用线程池?

    • 提升性能:减少频繁创建和销毁线程的开销。
    • 资源管理:防止因为创建太多线程导致系统资源耗尽。
    • 控制并发量:通过设置线程池大小,控制同时执行的任务数量。
  3. 线程池的主要组成部分

    • 核心线程数(corePoolSize):线程池中始终保持存活的线程数量。
    • 最大线程数(maximumPoolSize):线程池中允许的最大线程数量。
    • 任务队列(BlockingQueue):用于保存等待执行的任务。
    • 线程工厂(ThreadFactory):用于创建线程。
    • 拒绝策略(RejectedExecutionHandler):当任务过多时,如何处理无法执行的任务。

问题1:核心线程数和最大线程数分别指什么 举个具体例子

一、核心线程数(corePoolSize)

  • 核心线程数是线程池中始终存活的线程数量。
  • 即使线程处于空闲状态(没有任务可执行),这些核心线程也不会被销毁。
  • 只有任务超过核心线程数时,线程池才会创建非核心线程来执行任务。

二、最大线程数(maximumPoolSize)

  • 最大线程数是线程池中允许的最大线程数量。
  • 当任务数量超过核心线程数,且任务队列已满时,线程池会创建非核心线程(数量 = 最大线程数 - 核心线程数)来执行任务。
  • 如果任务数量超过了 最大线程数 + 队列容量,线程池会触发拒绝策略。

三、举例说明

假设我们有以下线程池配置:

  • 核心线程数(corePoolSize):3
  • 最大线程数(maximumPoolSize):5
  • 任务队列大小(BlockingQueue):2

初始状态:线程池中只有3个核心线程处于等待状态。

场景 1:任务数量 ≤ 核心线程数
  • 假设有 3 个任务 Task1, Task2, Task3
  • 线程池会直接分配这 3 个任务给核心线程,线程池中不会创建非核心线程。

执行情况

  • 核心线程 1 执行 Task1
  • 核心线程 2 执行 Task2
  • 核心线程 3 执行 Task3

线程池状态

  • 活跃线程数:3(核心线程)。
  • 队列任务数:0。

场景 2:任务数量 > 核心线程数,且任务队列未满
  • 假设有 5 个任务 Task1, Task2, Task3, Task4, Task5
  • 核心线程会优先执行 3 个任务,剩下的 2 个任务会被放入任务队列。

执行情况

  • 核心线程 1 执行 Task1
  • 核心线程 2 执行 Task2
  • 核心线程 3 执行 Task3
  • 队列中排队:Task4, Task5

线程池状态

  • 活跃线程数:3(核心线程)。
  • 队列任务数:2。

场景 3:任务数量 > 核心线程数 + 队列容量,且小于最大线程数
  • 假设有 7 个任务 Task1Task7
  • 核心线程会执行 3 个任务,任务队列能容纳 2 个任务。
  • 剩下的 2 个任务,线程池会创建非核心线程来执行。

执行情况

  • 核心线程 1 执行 Task1
  • 核心线程 2 执行 Task2
  • 核心线程 3 执行 Task3
  • 队列中排队:Task4, Task5
  • 非核心线程 1 执行 Task6
  • 非核心线程 2 执行 Task7

线程池状态

  • 活跃线程数:5(3 个核心线程 + 2 个非核心线程)。
  • 队列任务数:0(已被消耗完)。

场景 4:任务数量 > 最大线程数 + 队列容量
  • 假设有 10 个任务 Task1Task10
  • 核心线程执行 3 个任务,任务队列容纳 2 个任务,最大线程数支持 5 个线程。
  • 剩下的任务(Task8, Task9, Task10)会被拒绝策略处理。

执行情况

  • 核心线程 1 执行 Task1
  • 核心线程 2 执行 Task2
  • 核心线程 3 执行 Task3
  • 队列中排队:Task4, Task5
  • 非核心线程 1 执行 Task6
  • 非核心线程 2 执行 Task7
  • Task8, Task9, Task10 被拒绝(可能抛出异常或被记录在 discardTasks 中)。

线程池状态

  • 活跃线程数:5(3 个核心线程 + 2 个非核心线程)。
  • 队列任务数:0。
  • 被拒绝任务数:3。

四、总结线程池执行的优先级

  1. 优先用核心线程处理任务。
  2. 当核心线程都忙时,将任务加入队列。
  3. 当队列满了,创建非核心线程处理任务。
  4. 当非核心线程也不足以处理时,触发拒绝策略。

五、图示帮助理解

配置:
  • 核心线程数:3
  • 最大线程数:5
  • 队列大小:2

状态

核心线程队列非核心线程结果
提交 3 个任务300全部被核心线程执行
提交 5 个任务320队列满,无需非核心线程
提交 7 个任务322非核心线程执行 2 个
提交 10 个任务322拒绝 3 个任务

问题2:队列中的线程就是在等待吗 等核心线程任务执行完释放出来然后队列中的任务执行

回答:详细分析队列中任务的执行逻辑

  1. 当核心线程都在忙时
    新提交的任务会进入任务队列(BlockingQueue)。

    • 这些任务不会被直接执行,而是等待线程池中已有的线程(核心线程或非核心线程)空闲下来再去处理。
  2. 队列中的任务执行顺序
    队列中的任务遵循 先进先出(FIFO) 的原则,即最早进入队列的任务会最先被执行。

  3. 当核心线程完成当前任务后
    核心线程会从队列中取出下一个任务并开始执行。


执行过程举例

配置:
  • 核心线程数:2
  • 最大线程数:4
  • 队列容量:3
提交任务:Task1, Task2, Task3, Task4, Task5
  • 初始状态

    • 核心线程执行 Task1Task2
    • 任务队列中等待:Task3, Task4, Task5
  • 核心线程完成 Task1

    • Task3 从队列中出队,交给核心线程 1 执行。
    • 核心线程 2 继续执行 Task2
  • Task2 执行完后

    • Task4 从队列中出队,交给核心线程 2 执行。

总结

  • 队列中的任务确实是在 等待。它们需要等到有线程空闲时,才能被取出来执行。
  • 队列起到了“缓冲”的作用,使得线程池能够在任务量大时平稳运行,而不是直接创建过多线程。

问题3:场景三中的实例不太明白

回答:

"已被消耗完"的意思是 任务队列中的任务已经被线程处理了,任务队列不再有排队的任务。


详细讲解这个场景(7个任务,3核心线程,队列容量2,最大线程数5):

配置:
  • 核心线程数:3
  • 任务队列容量:2
  • 最大线程数:5
任务情况:
  • 提交任务Task1Task7

任务分配流程

  1. 首先使用核心线程执行任务

    • 核心线程 1 执行 Task1
    • 核心线程 2 执行 Task2
    • 核心线程 3 执行 Task3
    • 任务队列状态:空(因为还没有达到队列阶段)。
  2. 任务超过核心线程数,进入队列

    • Task4Task5 被放入队列中。
    • 任务队列状态[Task4, Task5]
    • 此时线程池的线程资源已经用满,核心线程都在工作中,队列的容量也达到了上限。
  3. 超过队列容量,创建非核心线程

    • Task6Task7 超出队列容量,无法再放入队列,线程池根据配置开始创建 非核心线程
      • 非核心线程 1 执行 Task6
      • 非核心线程 2 执行 Task7
  4. 执行任务的顺序

    • 核心线程 1 执行完 Task1 后,会从队列中取出 Task4 来执行。
    • 核心线程 2 执行完 Task2 后,会从队列中取出 Task5 来执行。
    • 非核心线程直接处理 Task6Task7,无需等待队列。

关于“队列任务被消耗完”的说明

当队列中的任务 Task4Task5 被核心线程取出并开始执行时,任务队列就会变为空,也就是 任务队列中的任务已经全部被线程“消耗”了,即任务被拿出来处理。

最终状态

  • 活跃线程数:5(3 个核心线程 + 2 个非核心线程)。
  • 队列状态:空(Task4Task5 已经被线程取出执行)。

举个日常生活中的例子来比喻:

假设你是一家餐厅老板:

  • 核心线程 = 厨房里固定的 3 名厨师。
  • 队列 = 等待下单的顾客排队区(只能排 2 人)。
  • 非核心线程 = 你从街上临时雇来的 2 名厨师帮忙应急。

场景:

  1. 最开始,固定的 3 名厨师(核心线程)正在同时制作菜品(Task1Task3)。
  2. 排队区的顾客(任务)慢慢满了,排了 2 人(Task4Task5)。
  3. 再有顾客来(Task6Task7),队列装不下了,你只能紧急雇佣临时厨师来处理这些任务。
  4. 最终,所有顾客(任务)都被安排制作,队列也空了(排队区没有人了)。

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

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

相关文章

Unity3d 基于UGUI和VideoPlayer 实现一个多功能视频播放器功能(含源码)

前言 随着Unity3d引擎在数字沙盘、智慧工厂、数字孪生等场景的广泛应用,视频已成为系统程序中展示时,不可或缺的一部分。在 Unity3d 中,我们可以通过强大的 VideoPlayer 组件和灵活的 UGUI 系统,将视频播放功能无缝集成到用户界面…

WebGAL 项目下载及安装教程

WebGAL 项目下载及安装教程 WebGAL A brand new web Visual Novel engine | 全新的网页端视觉小说引擎 [这里是图片001] 项目地址: https://gitcode.com/gh_mirrors/web/WebGAL 1、项目介绍 WebGAL 是一个全新的网页端视觉小说引擎,旨在提供美观、功能强大且易于…

虚幻引擎是什么?

Unreal Engine,是一款由Epic Games开发的游戏引擎。该引擎主要是为了开发第一人称射击游戏而设计,但现在已经被成功地应用于开发模拟游戏、恐怖游戏、角色扮演游戏等多种不同类型的游戏。虚幻引擎除了被用于开发游戏,现在也用于电影的虚拟制片…

Kubernetes 架构图和组件

🧑 博主简介:CSDN博客专家,历代文学网(PC端可以访问:历代文学,移动端可微信小程序搜索“历代文学”)总架构师,15年工作经验,精通Java编程,高并发设计&#xf…

GESP2024年12月认证C++五级( 第三部分编程题(2))

参考程序&#xff1a; #include<bits/stdc.h> using namespace std; #define ll long long int n, m; int cnt[1010]; vector<int> cs[1010]; ll calc(int aim) {int cur_cnt cnt[1];ll res 0;vector<int> tmp;for (int i 2; i<n; i){int buy max((…

基于DockerCompose搭建Redis主从哨兵模式

linux目录结构 内网配置 哨兵配置文件如下&#xff0c;创建3个哨兵配置文件 # sentinel26379.conf sentinel26380.conf sentinel26381.conf 内容如下 protected-mode no sentinel monitor mymaster redis-master 6379 2 sentinel down-after-milliseconds mymaster 60000 s…

npm error code ETIMEDOUT

参考:https://blog.csdn.net/qq_38572963/article/details/142052986 二、解决办法 1、清空缓存 npm cache clean --force 2、查看当前的npm镜像设置 npm config get registry 3、切换新镜像源 npm config set registry https://registry.npmmirror.com 4、查看新源是否设置成功…

【终端工具】FinalShell v4.5.12 官方版

1.下载地址 【终端工具】FinalShell v4.5.12 官方版 2.简介 FinalShell是一款免费的跨平台远程管理工具&#xff0c;专为开发者和运维人员设计。它支持通过 SSH、SFTP 等方式连接到 Linux 和 Windows 服务器&#xff0c;提供类似于终端的操作界面。除了常规的远程登录功能&a…

微前端qiankun的使用——实践

qiankun 创建主应用项目——vue2 main.js注册子应用 $ yarn add qiankun # 或者 npm i qiankun -Simport { registerMicroApps, start } from qiankun; import Vue from "vue"; import App from "./App.vue"; import router from "./router"; …

ansible play-book玩法

使用ansible-playbook实现安装nginx_ansible 安装nginx-CSDN博客文章浏览阅读1.5k次&#xff0c;点赞14次&#xff0c;收藏19次。本文详细介绍了如何在Linux环境中准备Ansible环境&#xff0c;包括配置主机、下载和安装Ansible&#xff0c;以及使用yum模块和tar包源码安装Nginx…

Require:离线部署 Sourcegraph

Sourcegraph 使读取、编写和修复代码变得容易——即使在庞大而复杂的代码库中。 代码搜索&#xff1a;搜索所有分支和所有代码主机的所有存储库。代码智能&#xff1a;导航代码、查找引用、查看代码所有者、跟踪历史记录等。修复和重构&#xff1a;一次对许多存储库进行大规模更…

大数据新视界 -- Hive 集群性能监控与故障排查(2 - 16 - 14)

&#x1f496;&#x1f496;&#x1f496;亲爱的朋友们&#xff0c;热烈欢迎你们来到 青云交的博客&#xff01;能与你们在此邂逅&#xff0c;我满心欢喜&#xff0c;深感无比荣幸。在这个瞬息万变的时代&#xff0c;我们每个人都在苦苦追寻一处能让心灵安然栖息的港湾。而 我的…

Windows搭建域控服务器时本地administrator账户密码不符合要求解决办法

cmd命令行执行以下命令&#xff0c;再重试&#xff1a; net user administrator /passwordreq:yesWindows Server 2016 域控服务器搭建教程&#xff1a;https://blog.csdn.net/u010091664/article/details/122072506

【研究生必备|学术会议|高录用|见刊后1个月检索】第三届材料科学与智能制造国际学术会议(MSIM2025)

用处 1. 学术交流 参加学术会议是展示您研究成果和获取反馈的绝佳机会。在会议上&#xff0c;您可以与来自各地的研究者进行深入交流&#xff0c;讨论最新的研究动态与趋势&#xff0c;分享经验与观点。 2. 拓展人脉 学术会议汇聚了来自不同高校和研究机构的优秀学者和学生。…

ubuntu开机进入initramfs状态

虚拟机卡死成功起后进入了initramfs状态&#xff0c;可能是跟文件系统有问题或者检索不到根文件系统&#xff0c;或者是配置错误&#xff0c;系统磁盘等硬件问题导致 开机后进入如下图的界面&#xff0c; 文中有一条提示 要手动fsck 命令修复 /dev/sda1 命令如下 fsck /de…

C# 线程安全集合

文章目录 引言一、ConcurrentBag<T>二、ConcurrentQueue<T>三、ConcurrentStack<T>四、ConcurrentDictionary<TKey, TValue>五、总结引言 在多线程编程环境中,多个线程可能同时访问和操作集合数据。如果使用普通集合,很容易引发数据不一致、错误结果…

S32K324 MCAL中的Postbuild和PreCompile使用

文章目录 前言Postbuild和PreCompile的概念MCAL中配置差异总结 前言 之前一直看到MCAL配置中有这个Postbuild和PreCompile的配置&#xff0c;但是不太清楚这两个的区别和使用方法。最近在使用中出现了相关问题&#xff0c;本文介绍一下MCAL中这两种配置的区别和使用。 Postbu…

中国电信网络下多方通话 SIP消息交互记录

如下表格记录了一个日志中,在中国电信网络下多方语音通话 发起方的 SIP消息交互记录,省略部分SIP消息,记录下和多方通话的重要SIP消息。 progress1:发起方A通过拨号盘呼叫B 此操作建立A和B之间的通话,网络会向终端分配QCI=1的专有承载。 同时此专有承载包含四个pkt_filt…

应用(APP)部署容器化演进之路

应用&#xff08;Application&#xff09;部署容器化演进之路 一、应用程序部署痛点 1.1 应用程序部署流程 举例&#xff1a;部署一个JAVA编程语言开发的Web应用&#xff0c;以War包放入Tomcat方式部署。 部署过程如下&#xff1a; 服务器配置运行环境:JAVA代码运行环境&am…

SDMTSP:粒子群优化算法PSO求解单仓库多旅行商问题,可以更改数据集和起点(MATLAB代码)

一、单仓库多旅行商问题 单仓库多旅行商问题&#xff08;Single-Depot Multiple Travelling Salesman Problem, SD-MTSP&#xff09;&#xff1a;&#x1d45a;个推销员从同一座中心城市出发&#xff0c;访问其中一定数量的城市并且每座城市只能被某一个推销员访问一次&#x…