【多线程】线程池

一、什么是线程池

线程池(Thread Pool)是一种多线程并发执行的设计模式,它通过维护一个线程集合来执行多个任务,避免频繁地创建和销毁线程,提高系统性能和响应速度。

就好比如你经营了一家餐饮店,你名下有专职外卖员,为了防止没生意和生意爆满,你就雇了五个骑手,这五个骑手就好比线程,然后每个骑手都能安排接送一些订单,相当于任务,然后还没执行的任务就记录到一个本子上,等骑手执行完手上的任务再回来继续执行本子上的任务。


 二、线程池的作用

  1. 线程复用:线程池中有多个线程可以重复使用,而不需要每次都创建新线程,减少了线程创建和销毁的开销。
  2. 任务队列:线程池内部有一个任务队列,当任务提交时,它们会先进入队列,等待线程池中的线程来执行。
  3. 线程管理:线程池负责管理线程的生命周期,控制最大线程数、最小线程数等。
  4. 任务调度:线程池按照设定的规则分配任务,保证任务的并发执行。

三、线程池的参数介绍

1. corePoolSize(核心线程数)

  • 定义:线程池中保持活动的最小线程数,即使这些线程处于空闲状态,它们也不会被销毁。
  • 作用:它是线程池中最少的线程数。如果线程池中的线程数量小于这个值,线程池会创建新的线程来处理任务。
  • 适用场景:当系统负载较重时,确保线程池有足够的线程可用来处理任务。

2. maximumPoolSize(最大线程数)

  • 定义:线程池能够容纳的最大线程数。当线程池中的线程数达到该值时,如果有新的任务提交,将根据workQueue的状态进行处理。
  • 作用:限制线程池可以创建的最大线程数,避免线程过多导致资源浪费或系统崩溃。
  • 适用场景:当任务量突增时,允许线程池创建更多的线程来处理任务,防止任务积压。

3. keepAliveTime(线程空闲存活时间)

  • 定义:当线程池中线程数量超过corePoolSize时,空闲线程存活的最大时间。超时后,空闲线程会被销毁,直到线程池中的线程数达到corePoolSize
  • 作用:控制线程池中空闲线程的生命周期,避免不必要的资源浪费。如果线程池中有多余线程,且线程空闲时间超过keepAliveTime,这些线程会被回收。
  • 适用场景:如果系统负载较低,线程池中的线程不需要一直存在,可以通过设置合理的keepAliveTime来减少资源占用。

4. workQueue(任务队列)

  • 定义:当线程池中的线程数量达到corePoolSize时,新的任务会被存入任务队列等待执行。常见的任务队列有:

    • SynchronousQueue:每个任务必须由一个线程来处理,否则会拒绝该任务(不允许任务排队)。
    • LinkedBlockingQueue:队列长度无限,任务会排队等待线程来执行,适用于任务数很多但线程数有限的情况。
    • ArrayBlockingQueue:队列长度有限,队列容量大小需要在创建时指定。
    • PriorityBlockingQueue:优先级队列,任务按优先级顺序处理。
  • 作用:任务队列决定了线程池如何管理和调度任务。如果所有线程都忙碌且任务队列已满,则新提交的任务会根据RejectedExecutionHandler策略处理。

5. ThreadFactory(线程工厂)

  • 定义:一个用于创建新线程的工厂接口。线程池使用这个工厂来创建新线程,而不是直接使用new Thread()
  • 作用:通过实现ThreadFactory接口,用户可以定制线程的创建方式,比如设置线程名称、优先级、是否为守护线程等。
  • 适用场景:需要定制线程属性的场景,例如给线程命名、设置线程的特定属性(如守护线程、优先级等)。

6. RejectedExecutionHandler(任务拒绝处理器)

  • 定义:当线程池中的线程数达到maximumPoolSize,并且任务队列已满时,新的任务提交会被拒绝执行。此时,RejectedExecutionHandler决定如何处理这些任务。

  • 常见策略

    • AbortPolicy:直接抛出RejectedExecutionException,默认策略。
    • CallerRunsPolicy:由调用者线程来执行任务,而不是由线程池中的线程来执行。
    • DiscardPolicy:丢弃当前任务,不抛出异常。
    • DiscardOldestPolicy:丢弃任务队列中最旧的任务,然后尝试提交当前任务。
  • 作用:当线程池达到最大容量并且任务队列已满时,确定如何应对新的任务请求。

7. AllowCoreThreadTimeOut(是否允许核心线程超时)

  • 定义:这是一个布尔值,表示是否允许核心线程在空闲时超时被销毁。如果设置为true,即使是核心线程也会在超时后被销毁;如果为false,核心线程永远不会被销毁。
  • 作用:允许核心线程在不使用时被销毁,节省系统资源。

四、线程池的工作流程

1.任务提交

当你通过submit()或者execute()方法向线程池提交任务时,线程池首先会判断当前线程池的状态。

2.任务队列的选择

线程池会根据线程池当前的状态(线程数、队列大小等)来决定任务去向:

  • 如果当前线程池中的线程数小于 corePoolSize(核心线程数):线程池会创建一个新的线程来执行任务,即使其他线程是空闲的。这时线程池没有达到核心线程数,所以新任务会直接交给新线程处理。

  • 如果当前线程池中的线程数已经等于或大于 corePoolSize:任务会被放入任务队列(workQueue)中等待。此时,不会创建新的线程,任务将等待已有线程去执行。

3. 执行任务

  • 如果任务在队列中等待:线程池中的线程会从队列中获取任务并执行。

  • 如果任务队列已满且线程数还未达到 maximumPoolSize:线程池会根据 maximumPoolSize 参数创建更多的线程来执行任务。

  • 如果任务队列已满且线程数已达到 maximumPoolSize:线程池无法再创建新的线程,新的任务会根据线程池的拒绝策略(RejectedExecutionHandler)来进行处理,常见的拒绝策略有:

    • AbortPolicy:直接抛出异常(默认策略)。
    • CallerRunsPolicy:由提交任务的线程来执行该任务。
    • DiscardPolicy:丢弃当前任务。
    • DiscardOldestPolicy:丢弃任务队列中最旧的任务,并尝试重新提交任务。

4. 线程的回收

  • 空闲线程回收:当线程池中的线程数超过 corePoolSize 且线程处于空闲状态,线程池会在等待一定时间后回收这些空闲线程。这个时间由 keepAliveTime 参数控制。

  • 核心线程回收:默认情况下,核心线程会一直保留,即使它们处于空闲状态。如果设置了 allowCoreThreadTimeOuttrue,那么核心线程也会在空闲时间超时后被回收。

5. 线程池关闭

当线程池执行完所有任务,调用 shutdown()shutdownNow() 方法后,线程池会进行关闭操作:

  • shutdown():线程池不会接受新的任务,但会继续执行已提交的任务,直到所有任务执行完毕,之后线程池才会关闭。

  • shutdownNow():会尽量停止正在执行的任务,并返回尚未执行的任务列表。这个方法会强制中止线程池的运行,但不能保证所有任务都能被成功中止。


五、使用Executors 创建常见的线程池

import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;public class ThreadPoolExample {public static void main(String[] args){//固定线程池ExecutorService fixedThreadPool= Executors.newFixedThreadPool(3);for(int i=0;i<5;i++){fixedThreadPool.submit(()->System.out.println(Thread.currentThread().getName()));}//缓存线程池ExecutorService cachedThreadPool = Executors.newCachedThreadPool();for (int i = 0; i < 5; i++) {cachedThreadPool.submit(() -> System.out.println(Thread.currentThread().getName() ));}//单线程池ExecutorService singleThreadExecutor = Executors.newSingleThreadExecutor();for (int i = 0; i < 5; i++) {singleThreadExecutor.submit(() -> System.out.println(Thread.currentThread().getName()));}//定时线程池ScheduledExecutorService scheduledThreadPool = Executors.newScheduledThreadPool(2);scheduledThreadPool.scheduleAtFixedRate(() -> System.out.println(Thread.currentThread().getName()), 0, 1, TimeUnit.SECONDS);}}

Executors 本质上是 ThreadPoolExecutor 类的封装. ThreadPoolExecutor 提供了更多的可选参数, 可以进一步细化线程池行为的设定。 

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

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

相关文章

【QT】: 初识 QWidget 控件 | QWidget 核心属性(API) | qrc 文件

&#x1f525; 目录 1. 控件概述 控件体系的发展阶段 2. QWidget 核心属性 2.1 核心属性概览2.2 用件可用&#xff08;Enabled&#xff09; 2.3 坐标系&#xff08;Geometry&#xff09; **实例 1: 控制按钮的位置**实例 2: 表白 程序 2.4 窗口标题&#xff08;windowTiltle&a…

CSS 合法颜色值

CSS 颜色 CSS 中的颜色可以通过以下方法指定&#xff1a; 十六进制颜色带透明度的十六进制颜色RGB 颜色RGBA 颜色HSL 颜色HSLA 颜色预定义/跨浏览器的颜色名称使用 currentcolor 关键字 十六进制颜色 用 #RRGGBB 规定十六进制颜色&#xff0c;其中 RR&#xff08;红色&…

C++第十五讲:异常

C第十五讲&#xff1a;异常 1.异常的概念和使用1.1异常的抛出和捕获1.2异常抛出和捕获的注意事项1.3异常的重新抛出1.4异常规范 2.标准库的异常 1.异常的概念和使用 1.1异常的抛出和捕获 异常的抛出和捕获的过程分为三个阶段&#xff1a; 1.异常的抛出&#xff1a; 使用throw对…

HTML<bdo>标签

例子 指定文本方向&#xff1a; <bdo dir"rtl"> This text will go right-to-left. </bdo> <!DOCTYPE html> <html> <body> <h1>The bdo element</h1> <p>This paragraph will go left-to-right.</p> …

Git:问题解决办法 及 Tips 总结

目录 查看历史记录及比较区别查看所有提交的历史记录查看提交的详细历史记录查看提交之间的差异点击文件操作历史&#xff0c;筛选出所有改动过此文件的提交任意两个提交之间的比较&#xff08;开发及查BUG常用&#xff09; 在需要版本回滚的情况下处理方法短时间内无法彻查BUG…

uniApp开通uniPush1.0个推,SpringBoot集成uniPush1.0个推

uniApp开通unipush1.0个推&#xff0c;SpringBoot程序集成 一、APP开通unipush1.0个推(商户App源码仅支持1.0个推) 1.app模块配置开通推送 2.应用开通推送 3.开通后点击消息推送菜单会看到如下页面 完成以上步骤后 此时android 仅支持在线推送。 4.配置各厂商离线推送 暂未…

[JavaScript] 深入理解流程控制结构

文章目录 1. **if-else 语句**基本语法&#xff1a;示例&#xff1a;扩展&#xff1a;else if 2. **switch-case 语句**基本语法&#xff1a;示例&#xff1a;注意事项&#xff1a; 3. **for 循环**基本语法&#xff1a;示例&#xff1a;扩展&#xff1a;for-in 和 for-of 4. *…

庄小焱——2024年博文总结与展望

摘要 大家好&#xff0c;我是庄小焱。岁末回首&#xff0c;2024 年是我在个人成长、博客创作以及生活平衡方面收获颇丰的一年。这一年的经历如同璀璨星辰&#xff0c;照亮了我前行的道路&#xff0c;也为未来的发展奠定了坚实基础。 1. 个人成长与突破 在 2024 年&#xff0c…

八大排序--冒泡排序

目录 什么是冒泡排序&#xff1f; 算法步骤 举例说明 代码实现&#xff08;java&#xff09; 什么是冒泡排序&#xff1f; 冒泡排序&#xff08;英语&#xff1a;Bubble sort&#xff09;是一种简单的排序算法。由于在算法的执行过程中&#xff0c;较小的元…

新阿里云买服务器配置需手动配置80端口

新买阿里云服务器需手动配置80&#xff0c;端口才可以访问nginx CentOS系统 安装nginx 1. 安装 Nginx yum install nginx 2. 启动 Nginx 服务 systemctl start nginx 3. 修改默认网页 cd /usr/share/nginx/ echo "666" >index.html cat index.html 访问ngin最后…

如何下载对应城市的地理json文件

这里采用的是阿里地图工具进行查找&#xff1a; DataV.GeoAtlas地理小工具系列 由阿里云DataV数据可视化团队出品,多年深耕数据可视化领域,数据大屏业务开拓者和领航者。致力用震撼而清晰的视觉语言,让更多人读懂大数据,受惠数据驱动的决策方式 第一步打开网站 &#xff1a; …

“libcudart,so.1 1.0“ loss解决方案

sudo find /usr/ -name libcudart.so.11.0 2 > /dev/null参考链接&#xff1a;1、https://stackoverflow.com/questions/70967651/could-not-load-dynamic-library-libcudart-so-11-0 2、https://blog.csdn.net/weixin_43786241/article/details/109203995

通过图形界面展现基于本地知识库构建RAG应用

1. 客户需求 快速完成概念验证(PoC)通过图形界面快速完成演示本地私有数据对比不同模型和成本&#xff0c;决定如何部署 2. 阿里云基于本地知识库构建RAG应用 参考方案&#xff1a; 百炼本地知识库方案 解决方案&#xff1a; FastAPI Gradio Llamaindex qwen-plus 主要三大…

安路FPGA开发工具TD:问题解决办法 及 Tips 总结

安路科技&#xff08;Anlogic&#xff09;是一家专注于高性能、低功耗可编程逻辑器件&#xff08;FPGA&#xff09;设计和生产的公司。其提供的开发工具TD&#xff08;TangDynasty&#xff09;是专门为安路FPGA系列产品设计的集成开发环境&#xff08;IDE&#xff09;。以下是对…

聚铭网络6款产品入选CCIA《网络安全专用产品指南》

近日&#xff0c;中国网络安全产业联盟CCIA正式发布《网络安全专用产品指南》&#xff08;第二版&#xff09;&#xff08;以下简称《指南》&#xff09;。聚铭网络凭借突出技术优势、创新能力以及市场积累&#xff0c;旗下安全产品成功入选防火墙、网络安全审计、日志分析、网…

渗透笔记1

第一天 工具&#xff1a;cs cobalt strike 4.9 / msf kali &#xff08;自带 Ubuntu&#xff09; cs cobalt strike 4.9&#xff1a;server-client server部署在云服务器上&#xff0c;client分别在各地&#xff0c;与server相连接&#xff1b;连接上后就可以共享上线主机。…

计算机网络 (51)鉴别

前言 计算机网络鉴别是信息安全领域中的一项关键技术&#xff0c;主要用于验证用户或信息的真实性&#xff0c;以及确保信息的完整性和来源的可靠性。 一、目的与重要性 鉴别的目的是验明用户或信息的正身&#xff0c;对实体声称的身份进行唯一识别&#xff0c;以便验证其访问请…

《Vue3 九》动画

Vue 提供了一些内置组件和对应的 API 来完成动画&#xff0c;利用它们可以方便地实现动画效果。 <transition> 内置组件&#xff1a; Vue 提供了 <transition> 内置组件&#xff0c;可以给任意元素或组件添加进入/离开时的动画效果。在条件渲染、动态组件、改变 …

人工智能之数学基础:线性代数中的线性相关和线性无关

本文重点 在线性代数的广阔领域中,线性相关与线性无关是两个核心概念,它们对于理解向量空间、矩阵运算、线性方程组以及人工智能等问题具有至关重要的作用。 定义与直观理解 当存在一组不全为0的数x1,x2,...,xn使得上式成立的时候,那么此时我们可以说向量组a1,a2...,an…

【王树森搜素引擎技术】相关性03:文本匹配(TF-IDF、BM25、词距)

链路上的相关性模型 召回海选 打分量&#xff1a;数万模型&#xff1a;文本匹配分数线性模型或双塔BERT模型 粗排 打分量&#xff1a;数千模型&#xff1a;双塔BERT&#xff0c;或单塔BERT模型&#xff08;交叉&#xff09; 精排 打分量&#xff1a;数百模型&#xff1a;单塔B…