一文搞懂 java 线程池:ThreadPoolExecutor 和 FixedThreadPool 原理

news2024/10/7 4:29:44

你好,我是 shengjk1,多年大厂经验,努力构建 通俗易懂的、好玩的编程语言教程。 欢迎关注!你会有如下收益:

  1. 了解大厂经验
  2. 拥有和大厂相匹配的技术等

希望看什么,评论或者私信告诉我!

文章目录

  • 一、前言
  • 二、线程池原理
    • 2.1 ThreadPoolExecutor 原理
    • 2.2 ThreadPoolExecutor的 execute 方法原理
    • 2.3 FixedThreadPool
      • 2.3.1 FixedThreadPool 简介
      • 2.3.2 FixedThreadPool 的 execute 方法原理
      • 2.3.2 FixedThreadPool 优缺点及应用场景
  • 三、总结

一、前言

上一章节我们详解介绍了线程池的一些关键性知识。这章我们会详细介绍各个线程池的原理

二、线程池原理

2.1 ThreadPoolExecutor 原理

从图中可以看出,当提交一个新任务到线程池时,线程池的处理流程如下。

  1. 线程池判断核心线程池里的线程是否都在执行任务。如果不是,则创建一个新的工作线程来执行任务。如果核心线程池里的线程都在执行任务,则进入下个流程。
  2. 线程池判断工作队列是否已经满。如果工作队列没有满,则将新提交的任务存储在这个工作队列里。如果工作队列满了,则进入下个流程。
  3. 线程池判断线程池的线程是否都处于工作状态。如果没有,则创建一个新的工作线程来执行任务。如果已经满了,则交给饱和策略来处理这个任务

2.2 ThreadPoolExecutor的 execute 方法原理

ThreadPoolExecutor执行execute方法分下面4种情况。

  1. 如果当前运行的线程少于corePoolSize,则创建新线程来执行任务(注意,执行这一步骤需要获取全局锁)。
  2. 如果运行的线程等于或多于corePoolSize,则将任务加入BlockingQueue。
  3. 如果无法将任务加入BlockingQueue(队列已满),则创建新的线程来处理任务(注意,执行这一步骤需要获取全局锁)。
  4. 如果创建新线程将使当前运行的线程超出maximumPoolSize,任务将被拒绝,并调用RejectedExecutionHandler.rejectedExecution()方法。

ThreadPoolExecutor采取上述步骤的总体设计思路,是为了在执行execute()方法时,尽可能地避免获取全局锁(那将会是一个严重的可伸缩瓶颈)。在ThreadPoolExecutor完成预热之后(当前运行的线程数大于等于corePoolSize),几乎所有的execute()方法调用都是执行步骤2,而步骤2不需要获取全局锁。

2.3 FixedThreadPool

2.3.1 FixedThreadPool 简介

FixedThreadPool被称为可重用固定线程数的线程池,通过上一篇我们知道它是通过 ThreadPoolExecutor 来实现的,下面是FixedThreadPool的源代码实现。

public static ExecutorService newFixedThreadPool(int nThreads) {
    return new ThreadPoolExecutor(nThreads, nThreads,
                                  0L, TimeUnit.MILLISECONDS,
                                  new LinkedBlockingQueue<Runnable>());
}

FixedThreadPool的corePoolSize和maximumPoolSize都被设置为创建FixedThreadPool时指定的参数nThreads。

当线程池中的线程数大于corePoolSize时,keepAliveTime为多余的空闲线程等待新任务的最长时间,超过这个时间后多余的线程将被终止。这里把keepAliveTime设置为0L,意味着多余的空闲线程会被立即终止

2.3.2 FixedThreadPool 的 execute 方法原理

  1. 如果当前运行的线程数少于corePoolSize,则创建新线程来执行任务。
  2. 在线程池完成预热之后(当前运行的线程数等于corePoolSize),将任务加入LinkedBlockingQueue。
  3. 线程执行完1中的任务后,会在循环中反复从LinkedBlockingQueue获取任务来执行。FixedThreadPool使用无界队列LinkedBlockingQueue作为线程池的工作队列(队列的容量为Integer.MAX_VALUE)。

使用无界队列作为工作队列会对线程池带来如下影响。

  1. 当线程池中的线程数达到corePoolSize后,新任务将在无界队列中等待,因此线程池中的线程数不会超过corePoolSize。
  2. 由于1,使用无界队列时maximumPoolSize将是一个无效参数。
  3. 由于1和2,使用无界队列时keepAliveTime将是一个无效参数。
  4. 由于使用无界队列,运行中的FixedThreadPool(未执行方法shutdown()或shutdownNow())不会拒绝任务(不会调用RejectedExecutionHandler.rejectedExecution方法)

2.3.2 FixedThreadPool 优缺点及应用场景

FixedThreadPool 是一个固定大小的线程池,在实际应用中有一些适合的场景和优点:

适用场景:

  1. 资源管理:FixedThreadPool 适合于资源受限的情况,因为它可以限制并发线程的数量,避免资源耗尽或者系统负载过高。
  2. 任务一致性:适合执行一组数量固定的相同类型或相似类型的任务,这样可以保持线程池中的线程数量恒定。
  3. 控制并发度:适合于需要限制并发度的场景,比如执行文件处理、网络请求或数据库操作,以避免并发线程过多而导致性能下降。
  4. 简单任务:适合于执行较为简单的短时任务,因为固定大小的线程池可以降低线程的创建和销毁开销。
  5. 避免资源竞争:适合于避免因为线程数量过多导致资源竞争和线程调度开销较大的情况。

优点:

  1. 固定线程数:FixedThreadPool 的线程数量固定,可以更好地控制系统的并发度,避免过多的线程导致资源消耗和线程调度开销。
  2. 资源管理:对于有限的资源环境,在 ThreadPool 中固定线程数可以更好地管理资源,避免资源耗尽问题。
  3. 优化性能:固定大小的线程池可以避免线程创建和销毁的开销,对于执行频繁的任务能够提升性能。
  4. 任务排队:当任务数量大于线程池大小时,FixedThreadPool 中的任务会被放入队列中等待执行,保证任务不会丢失。

示例场景:

  • Web 服务器中处理请求:对于固定数量的请求处理器线程池,能够控制同时处理请求数量,避免处理请求的过度延迟。
  • 数据库查询:限制并发的数据库查询线程数量,避免数据库连接过度消耗。
  • 后台任务处理:用于处理一些耗时任务,比如定时检查或清理任务。
  • 池化资源管理:对于有限数量的资源如连接池、线程池等管理。

FixedThreadPool 的固定线程数量能够让你更好地控制系统资源的分配和线程的使用,适用于一些需求稳定并且相对简单的线程管理场景。

三、总结

文章深入解析了Java中线程池的核心工作机制,重点阐释了ThreadPoolExecutor如何管理线程和任务,以及FixedThreadPool在实际应用中的适用场景、优点和局限性。通过具体源代码和执行流程分析,让读者对线程池的实现原理有了清晰的认识。

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

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

相关文章

数据结构-排序算法篇

前言 在我们的生活中有很多东西都是有大小的&#xff0c;那么该如何去排序&#xff1f;假设有10个数字要你去排序&#xff0c;眼睛一扫就看出来了&#xff0c;那100、1000、10000要怎么去排&#xff1f;下面就为大家介绍各种排序的算法。 内容 1.冒泡排序 2.选择排序 3.插入…

某Dota/IM对战平台玩家助手、查看战绩下、胜率等

功能说明 WAR3游戏启动后&#xff0c;可以自动获取游戏双方的玩家列表&#xff0c;然后查询显示玩家的战绩及个人信息。附带查看玩家的战绩详情、最近游戏&#xff0c;查看对手及友方的战绩详情&#xff0c;据此推算出是否开黑、是否小号等信息 使用方法及运行效果 启动 查…

武汉星起航:贴心服务引领,跨境电商成功启航

在当今全球互联互通日益加强的背景下&#xff0c;跨境电商已经跃升为驱动国际贸易繁荣的重要引擎。作为全球电商领域的翘楚&#xff0c;亚马逊坚守公平、公正、透明的商业准则&#xff0c;为全球卖家搭建了一个值得信赖的交易平台。在这个平台上&#xff0c;众多卖家通过提升产…

如何指定Microsoft Print To PDF的输出路径

在上一篇文章中&#xff0c;介绍了三种将文件转换为PDF的方式。默认情况下&#xff0c;在Microsoft Print To PDF的首选项里&#xff0c;是看不到输出路径的设置的。 需要一点小小的手段。 运行输入 control 打开控制面板&#xff0c;选择硬件和声音下的查看设备和打印机 找到…

Django 多对多关系

多对多关系作用 Django 中&#xff0c;多对多关系模型的作用主要是为了表示两个模型之间的多对多关系。具体来说&#xff0c;多对多关系允许一个模型的实例与另一个模型的多个实例相关联&#xff0c;反之亦然。这在很多实际应用场景中非常有用&#xff0c;比如&#xff1a; 博…

Ceyear®VSA 信号分析软件

CeyearVSA 信号分析软件 CeyearVSA 矢量信号分析软件 CeyearVSA 矢量信号分析软件将信号分析体验和测试应用于桌面&#xff0c;帮助排查问题并优化设计。 CeyearVSA 矢量信号分析软件结合仪表支持在线解调分析&#xff0c;也可支持信号导入离线分析&#xff1b;软件具有多种…

搜狐新闻HarmonyOS版本 push 推送开发

背景 搜狐新闻作为HarmonyOS的合作伙伴&#xff0c;于2023年12月成功上架鸿蒙单框架应用市场&#xff0c;成为首批鸿蒙应用矩阵的一员。 新闻类推送作为应用的重要组成部分&#xff0c;在二期规划中&#xff0c;我们将推送功能列为核心功能模块。本文将推送集成过程中的步骤和…

oracle体系结构详解(实例+数据文件)

提示&#xff1a;主要总结oracle数据库&#xff1a;物理结构&#xff0c;逻辑结构&#xff0c;内存结构以及oracle进程 文章目录 Oracle服务器由&#xff08;实例和数据库文件组成&#xff09;1、实例2、数据文件1.oracle物理体系结构2.oracle数据库逻辑结构3oracle数据库内存结…

Log4j日志框架讲解(全面,详细)

Log4j概述 Log4j是Apache下的一款开源的日志框架&#xff0c;通过在项目中使用 Log4J&#xff0c;我们可以控制日志信息输出到控制台、文件、甚至是数据库中。我们可以控制每一条日志的输出格式&#xff0c;通过定义日志的输出级别&#xff0c;可以 更灵活的控制日志的输出过程…

【前端vue3】TypeScrip-类型推论和类型别名

类型推论 TypeScript里&#xff0c;在有些没有明确指出类型的地方&#xff0c;类型推论会帮助提供类型。 例如&#xff1a; 变量xiaoc被推断类型为string 如重新给xiaoc赋值数字会报错 let xiaoc "xiaoc"xiaoc 1111111111111如没有给变量指定类型和赋值&#xf…

阿里Nacos下载、安装(保姆篇)

文章目录 Nacos下载版本选择Nacos安装Windows常见问题解决 更多相关内容可查看 Nacos下载 Nacos官方下载地址&#xff1a;https://github.com/alibaba/nacos/releases 码云拉取&#xff08;如果国外较慢或者拉取超时可以试一下国内地址&#xff09; //国外 git clone https:…

RabbitMQ进阶篇

文章目录 发送者的可靠性生产者重试机制实现生产者确认 MQ的可靠性数据持久化交换机持久化队列持久化消息持久化 Lazy Queue(可配置~)控制台配置Lazy模式代码配置Lazy模式更新已有队列为lazy模式 消费者的可靠性消费者确认机制失败重试机制失败处理策略 业务幂等性唯一消息ID业…

编译libvlccpp

首先下载vlc sdk https://get.videolan.org/vlc/3.0.9.2/win64/vlc-3.0.9.2-win64.7z Cmake 生成libvlccpp vs2022工程文件 编译libvlccpp 编译出错需修改代码 错误信息&#xff1a; \VLC\sdk\include\vlc/libvlc_media.h(368): error C2065: “libvlc_media_read_cb”: 未…

Linux高并发服务器开发(九)Tcp状态转移和IO多路复用

文章目录 0 包裹函数1 多进程服务器流程代码 2 多线程服务器3 TCP状态转移半关闭心跳包 4 端口复用5 IO多路复用技术高并发服务器 6 select代码总结 7 POLLAPI代码poll相对select的优缺点 8 epoll&#xff08;重点&#xff09;API监听管道代码EPOLL 高并发服务器 9 Epoll的两种…

【MySQL备份】Percona XtraBackup加密备份实战篇

目录 1.前言 2.准备工作 2.1.环境信息 2.2.配置/etc/my.cnf文件 2.3.授予root用户BACKUP_ADMIN权限 2.4.生成加密密钥 2.5.配置加密密钥文件 3.加密备份 4.优化加密过程 5.解密加密备份 6.准备加密备份 7.恢复加密备份 7.1.使用rsync进行恢复 7.2.使用xtrabackup命令恢…

go Channel原理 (四)

Channel 设计原理 不要通过共享内存的方式进行通信&#xff0c;而是应该通过通信的方式共享内存。 在主流编程语言中&#xff0c;多个线程传递数据的方式一般都是共享内存。 Go 可以使用共享内存加互斥锁进行通信&#xff0c;同时也提供了一种不同的并发模型&#xff0c;即通…

终极指南:RNNS、Transformers 和 Diffusion 模型

一、说明 作为广泛使用这些工具和模型的人&#xff0c;我的目标是解开 RNN、Transformer 和 Diffusion 模型的复杂性和细微差别&#xff0c;为您提供详细的比较&#xff0c;为您的特定需求提供正确的选择。 无论您是在构建语言翻译系统、生成高保真图像&#xff0c;还是处理时间…

【ACM出版,马来西亚-吉隆坡举行】第四届互联网技术与教育信息化国际会议 (ITEI 2024)

作为全球科技创新大趋势的引领者&#xff0c;中国不断营造更加开放的科技创新环境&#xff0c;不断提升学术合作的深度和广度&#xff0c;构建惠及各方的创新共同体。这是对全球化的新贡献&#xff0c;是构建人类命运共同体的新贡献。 第四届互联网技术与教育信息化国际学术会议…

【CSAPP】-binarybomb实验

目录 实验目的与要求 实验原理与内容 实验设备与软件环境 实验过程与结果&#xff08;可贴图&#xff09; 操作异常问题与解决方案 实验总结 实验目的与要求 1. 增强学生对于程序的机器级表示、汇编语言、调试器和逆向工程等方面原理与技能的掌握。 2. 掌握使用gdb调试器…

【ONLYOFFICE】| 桌面编辑器从0-1使用初体验

目录 一. &#x1f981; 写在前面二. &#x1f981; 在线使用感受2.1 创建 ONLYOFFICE 账号2.2 编辑pdf文档2.3 pdf直接创建表格 三. &#x1f981; 写在最后 一. &#x1f981; 写在前面 所谓桌面编辑器就是一种用于编辑文本、图像、视频等多种自媒体的软件工具&#xff0c;具…