#详细介绍!!!线程池
本篇详细:
1.介绍了什么是线程池
2.使用线程池有什么好处
3.线程池的工作流程
4.线程池的各个参数介绍
5.如何编写Java代码来创建线程池
6.使用线程池的注意事项
目录
一:什么是线程池
二:为什么使用线程池来管理线程
三:线程池的工作流程
四:线程池的各个参数介绍
五:使用Java代码创建线程池
5.1 依靠Executors工厂类来创建
5.2 依靠ThreadPoolExecutor类来创建
六:使用线程池的注意事项
1.合理的设置线程的数量

一:什么是线程池
线程池总的来说:就是创建的一个进行线程管理的容器集合,主要为了提高管理线程效率,是一种多线程处理的形式。
线程池:就是开发者根据需求创建多个线程放到一个池中(逻辑意义上),来统一管理这些线程,由池中的任务队列来直接给池中的空闲线程分配任务,大致为这样的一个过程

二:为什么使用线程池来管理线程
使用线程池的主要目的就是提高线程的调度执行和管理上的效率
优势:
1.降低资源的开销
没有线程池时线程的创建和销毁一般是由操作系统来进行的,而操作系统对线程的控制一般又是不可控的,那么当线程超过空闲时间,而线程就可能会被自动销毁,此时这中反复的操作就有可能出现线程频繁创建和销毁的情况,虽然说线程的创建和销毁的效率对比进程已经优化了很多,但是依旧会造成大量的系统资源上的浪费。
那么如果利用线程池来集中创建线程进行管理,并且核心线程创建完成后,没任务也不会进行销毁。此时就大大减少了系统频繁对线程的创建和销毁造成的资源浪费了。
2.提高任务的响应速度
任务需要线程来执行,而线程由系统进行调度又是无序的,那么就有可能在任务过多时,导致系统响应该任务过慢,此时这种把任务直接让系统来分配线程执行,我们称为用户态+内核态。
当我们(用户)把一个任务交给系统来分配线程(内核)来进行执行时,此时系统不一定会直接响应去执行我们的任务,因为系统需要同时处理大量的响应,导致任务获得响应的速度较低。
如果使用我们自己创建的线程池来进行任务的响应,那么此时就是一个纯用户态的操作了。
因为线程池中有自己的线程,去执行线程池对应的任务队列中的任务,当线程空闲就直接去队列中获取其他任务,直接响应;且由于有核心线程的存在,此时线程池中的核心线程一直都在,并不会被销毁,此时也省去了创建线程进行的时间开销,进一步使得响应速度变快。
3.可管理性
利用线程池集中统一管理,监控池中的线程,避免由于线程数量过多且线程之间相互进行抢占系统资源导致线程大面积堵塞
三:线程池的工作流程
大致如下图:

1.线程池在创建时,就会指定好各个参数的数量(例如:核心线程,临时线程等)
2.线程池有一个与之对应的任务队列(由于线程池作用的环境一般是多线程并发的状态,此时任务队列也是线程安全的数据结构)
3.我们在使用线程池时只需要往线程池的任务队列中添加任务,此时
3.1如果池中的线程小于核心线程数就会创建核心线程再执行任务,且执行完不进行销毁
3.2如果池中的线程大于核心线程数,小于临时线程数,此时就会把任务分配给空闲的线程如果线程全部都被占用此时就会创建临时线程来执行任务
3.3如果池中线程数已满(核心线程数+临时线程数),此时就会运行线程池的拒绝策略
注意:线程池的拒绝策略后面单独进行讲解(重点面试题)
四:线程池的各个参数介绍
查看官方文档:
查看官方文挡,线程池的构造方法,我们可以看到如下的参数

参数介绍:
1. int corePoolSize :核心线程数
线程池中的核心线程创建之后就不会被销毁,需要用的时候,直接安排任务
2. int maximumPoolSize:最大线程数
最大线程数就是线程池允许同时存在的线程的最大数量:核心线程数+临时线程数
临时线程在执行完任务之后,空闲一定的时间会自动销毁,需要用的时候再创建
3.long keepAliveTime:临时线程的空闲存活时间
与第2个对应,临时线程空闲一定时间后会自动销毁,而keepAliveTime就是设置的空闲时间
4.TimeUnit unit:时间单位
时间参数的单位:例如TimeUnit SECOND(秒),设置时间单位为秒
5.BlockingQueue<Runnable> workQueue:堵塞队列(用于记录存储需要执行的任务)
workQueue就是我们前面一直说的任务队列,线程池中都有一个用于记录任务的队列
BlockingQueue 为一个线程安全的阻塞队列,参数为Runnable:为一个实际任务,通过重写重写run方法来描述具体的任务逻辑
6.ThreadFactory threadFactory:工厂类:用于辅助线程创建的类(参考工厂模式)
7.RejectedExecutionHandler handler:线程池的拒绝策略
指定线程池的拒绝策略,如果线程池满了,依旧在添加任务,那么就可根据设置的拒绝策略来进行拒绝(专门讲线程池拒绝策略的时候再详细介绍)
五:使用Java代码创建线程池
5.1 依靠Executors工厂类来创建
1. newFixedThreadPool(int n),返回类型为ExecutorService接口类型
指定线程池中线程的数量为n,并且这些线程都为核心线程
ExecutorService pool = Executors.newFixedThreadPool(10);
2.newSingleThreadPool(),返回类型为ExecutorService接口类型
单例线程池,固定线程池中的线程数量为1,且为核心线程
ExecutorService pool = Executors.newSingleThreadExecutor();
3.newCatchThreadPool(),返回类型为ExecutorService接口类型
创建的线程池中核心线程数为0,最大线程数为Integer.MAX_VALUE
keepAliveTime:60 ; TimeUnit为SECOND(秒):临时线程空闲等待时间为60秒,时间到了自动销毁
总结:以这种方式创建的线程池,池中的线程都是临时线程
ExecutorService pool = Executors.newCachedThreadPool();
4.newScheduledThreadPool(int n),返回类型为ScheduledExecutorSerives接口类型
定时任务线程池:其中可设置池中线程定时或者周期性的执行池中的任务
n为核心线程数
介绍几种该线程池的安排任务的方法区别
4.1 调用schedule方法个线程池安排任务(普通定时任务)
4.2 调用scheduleAtFixedRate方法给线程池安排周期性任务(从任务开始时计算周期定时时间)
4.3调用scheduleWithFixedDelay方法给线程池安排周期性任务(从任务结束开始计算周期定时时间)
//1.普通定时任务
pool.scheduleAtFixedRate(new Runnable() {@Overridepublic void run() {System.out.println("hello1");}
},2,TimeUnit.SECONDS);//2.周期任务
pool.scheduleAtFixedRate(new Runnable() {@Overridepublic void run() {System.out.println("hello1");}
},2,5,TimeUnit.SECONDS);//3.周期任务
pool.scheduleWithFixedDelay(new Runnable() {@Overridepublic void run() {System.out.println("hello2");}
},2,5,TimeUnit.SECONDS);
上诉三个代码的作用:
1. 安排了一个打印hello1的任务,定时2秒后执行任务
2.安排了一个周期性打印hello2的任务,定时2秒后执行,并且从任务开始执行时开始计算,5秒后再次执行该任务,以这种周期执行
3.安排了一个周期性打印hello3的任务,定时2秒后执行,并且从任务结束是开始计算周期间隔时间,间隔时间为5秒
5.newSingleThreadScheduleExecutor();返回类型为ScheduledExecutorSerives接口类型
单个线程的定时任务或者周期任务的线程池。池中只有一个线程,其他与4基本一致
ScheduledExecutorService pool = Executors.newSingleThreadScheduledExecutor();
5.2 依靠ThreadPoolExecutor类来创建
通过ThreadPoolExecutor类来更加灵活的创建线程池,根据ThreadPoolExecutor类的构造方法传递一系列参数进行灵活创建。
代码:
BlockingQueue<Runnable> queue = new LinkedBlockingQueue<>();ThreadPoolExecutor pool = new ThreadPoolExecutor(5,10,60,TimeUnit.SECONDS,queue);
指定一个线程安全的阻塞队列来存储线程池中的任务,
new ThreadPoolExecutor(5,10,60,TimeUnit.SECONDS,queue):
表示corePoolSize(核心线程数)为5;maximumPoolSize(最大线程数)为10
keepAliveTime(临时线程最大空闲时间)为60;TimeUnit.SECOND:单位为秒
queue为任务队列
当然还可以根据需求增加其他参数,参数详情参照前面线程池参数介绍
六:使用线程池的注意事项
1.合理的设置线程的数量
线程池的工作线程数设置应根据实际情况配置,CPU密集型业务(搜索、排序等)CPU空闲时间较少,线程数就不需要设置太多。N核服务器,通过执行业务的单线程分析出本地计算时间为x,等待时间为y,则工作线程数(线程池线程数)设置为 N*(x+y)/x,能让CPU的利用率最大化
相关文章:
#详细介绍!!!线程池
本篇详细: 1.介绍了什么是线程池 2.使用线程池有什么好处 3.线程池的工作流程 4.线程池的各个参数介绍 5.如何编写Java代码来创建线程池 6.使用线程池的注意事项 目录 一:什么是线程池 二:为什么使用线程池来管理线程 三:线程池…...
【嵌入式Linux学习笔记】基于Linux官方库的标准外设驱动
对于标准的外设如LED,KEY,PWM等,以及标准通信协议,Linux都自带有标准的驱动库,不需要我们自行编写,只需要配置好相应的GPIO属性和电气属性,即可匹配相应的驱动,在应用程序中直接使用…...
网络爬虫抓包工具
📚介绍:Charles是著名的抓包工具🐂,可以抓取移动端与pc端网络访问🕷的所有数据。我们将使用它抓取我们与小程序交互的所有信息。🎇我们可以百度搜索Charles官网下载适用于自己系统的Charles安装包…...
蓝桥杯倒计时 | 倒计时17天
作者🕵️♂️:让机器理解语言か 专栏🎇:蓝桥杯倒计时冲刺 描述🎨:蓝桥杯冲刺阶段,一定要沉住气,一步一个脚印,胜利就在前方! 寄语💓:…...
【Spring Cloud Alibaba】7.Sentinel熔断器仪表盘监控
文章目录简介什么是 Sentinel控制台获取源码方式下载jar包方式启动访问服务配置项目,启用Sentinel完整配置测试简介 接下来我们通过Sentinel控制台来实现对服务消费者提供的熔断机制进行监控和控制,本操作先要完成之前的步骤,详情请参照【Sp…...
个人博客系统项目测试报告
项目背景介绍 背景:当在学习一项技能的时候,我们总会习惯通过博客来记录所学的知识点,方便后期遗忘时随时查看和快速复习。本次开发的Web网站程序便是为了更加轻量和方便地记录自己的学习笔记 概述:一个Web网站程序,…...
flutter安装自用笔记
参照文章: 开发环境搭建 Flutter环境配置步骤: 1.系统配置要求 2.Java环境 3.Flutter SDK 4.Android 开发环境一、系统配置要求 操作系统:Windows 7 SP1 或更高的版本(基于 x86-64 的 64 位操作系统) 磁盘空间&…...
tomcat线程池以及在SpringBoot中的启动过程
tomcat两大组件:连接器Connector,容器Container tomcat线程池 Tomcat线程池扩展了ThreadPoolExecutor,行为稍有不同 重写了ThreadPoolExecutor的execute方法 如果总线程数达到maximumPoolSize,不会立刻抛RejectedExecutionExcept…...
第十四届中国大学生创新创业大赛
文章目录比赛官网比赛题目含金量非常高建议参加的学生推荐几个我感兴趣的题目联系比赛官网 官网地址:http://www.fwwb.org.cn/ 实际叫做:中国大学生创新创业大赛 比赛题目 题目公布查看地址:http://www.fwwb.org.cn/topic/index 题目有…...
LeetCode:322. 零钱兑换——动态规划从案例入门
🍎道阻且长,行则将至。🍓 🌻算法,不如说它是一种思考方式🍀算法专栏: 👉🏻123 一、🌱322. 零钱兑换 题目描述:给你一个整数数组coins,…...
【lwIP(第四章)】网络接口
目录一、lwIP网络接口简介二、lwIP的netif结构三、lwIP的netif相关函数1. lwIP网络接口的全局变量2. netif_add()函数3. netif_remove()函数4. netif_set_default()函数一、lwIP网络接口简介 lwIP协议栈支持多种不同的网络接口(网卡),由于网卡…...
Vue3 pinia入门篇(一)
系列文章目录 主要为了记录如何使用Pinia在Vue3中的使用方式(下面会介绍为什么使用Vue3选型) 文章目录系列文章目录不用Vue2使用Pinia举例子?1.笔者的个人看法:2.总结一、Pinia是什么1.状态管理工具(类比Vuexÿ…...
python面向对象编程解释
python是一个面向对象的编程语言 面向过程的开发语言有C,面向对象除了python还有java等语言 具体来讲: 面向过程 :举个例子,比如说,把大象装进冰箱总共分几步,第一步,把冰箱门打开,…...
ARM(IMX6U)嵌入式软件裸机开发之环境搭建与配置
目录 前沿 Ubuntu 和 Windows 文件互传 Ubuntu 下 NFS 和 SSH 服务开启 Ubuntu 交叉编译工具链安装 Source Insight 软件安装和使用 Visual Studio Code 软件的安装和使用 前沿 为什么我们要学习裸机开发呢? 1、裸机开发是了解所使用的 CPU 最直接、最简单的方…...
Java文件复制多种方法
1、InputStream与OutputStream 创建两个文件 - 源和目标。然后我们从源创建InputStream并使用OutputStream将其写入目标文件进行 java 复制文件操作。 private static void copyFileUsingStream(File source, File dest) throws IOException {InputStream is null;OutputStr…...
Java语言-----封装、继承、抽象、多态、接口
目录 前言 一.封装 1.1封装的定义 1.2访问修饰符的使用 二.继承 2.1继承的定义 2.2继承的方法 2.3继承使用注意点 三.多态 3,1多态的定义 3.2动态绑定 3.3方法重写 3.4向上(向下)转型 四.抽象 4.1抽象的概述和定义 4.2抽象的使用 五…...
基于深度学习的瓶子检测软件(UI界面+YOLOv5+训练数据集)
摘要:基于深度学习的瓶子检测软件用于自动化瓶子检测与识别,对于各种场景下的塑料瓶、玻璃瓶等进行检测并计数,辅助计算机瓶子生产回收等工序。本文详细介绍深度学习的瓶子检测软件,在介绍算法原理的同时,给出Python的…...
仿网易云小程序(一)
目录 一、项目准备 二、项目初始化 1.新建项目 2.封装service请求 三、底部导航栏的设计 四、MV页面的设计 1.将获取到的数据进行渲染 2.播放量数据进行处理转换 3.时长数据进行处理转换 五、MV组件的抽离封装 六、请求的抽离video 七、下拉重新请求新的数据 八、跳转到…...
【C++】vector模拟实现及其应用
文章目录vector的介绍vector的使用及其实现vector的定义vector iterator 的使用vector空间增长问题vector的增删查改vector的介绍 vector是表示可变大小数组的序列容器。就像数组一样,vector也采用的连续存储空间来存储元素。也就是意味着可以采用下标对vector的元素…...
JS看这一篇就够啦,JS基础大全,可用于快速回顾知识,面试首选
1 JS简介 更多JS内容可以看MDN:点击传送 浏览器分成两部分:渲染引擎和 JS 引擎 渲染引擎:用来解析HTML与CSS,俗称内核,比如 chrome 浏览器的 blink ,老版本的 webkitJS 引擎:也称为 JS 解释器…...
XCTF-web-easyupload
试了试php,php7,pht,phtml等,都没有用 尝试.user.ini 抓包修改将.user.ini修改为jpg图片 在上传一个123.jpg 用蚁剑连接,得到flag...
【ROS】Nav2源码之nav2_behavior_tree-行为树节点列表
1、行为树节点分类 在 Nav2(Navigation2)的行为树框架中,行为树节点插件按照功能分为 Action(动作节点)、Condition(条件节点)、Control(控制节点) 和 Decorator(装饰节点) 四类。 1.1 动作节点 Action 执行具体的机器人操作或任务,直接与硬件、传感器或外部系统…...
华为OD机试-食堂供餐-二分法
import java.util.Arrays; import java.util.Scanner;public class DemoTest3 {public static void main(String[] args) {Scanner in new Scanner(System.in);// 注意 hasNext 和 hasNextLine 的区别while (in.hasNextLine()) { // 注意 while 处理多个 caseint a in.nextIn…...
pikachu靶场通关笔记22-1 SQL注入05-1-insert注入(报错法)
目录 一、SQL注入 二、insert注入 三、报错型注入 四、updatexml函数 五、源码审计 六、insert渗透实战 1、渗透准备 2、获取数据库名database 3、获取表名table 4、获取列名column 5、获取字段 本系列为通过《pikachu靶场通关笔记》的SQL注入关卡(共10关࿰…...
佰力博科技与您探讨热释电测量的几种方法
热释电的测量主要涉及热释电系数的测定,这是表征热释电材料性能的重要参数。热释电系数的测量方法主要包括静态法、动态法和积分电荷法。其中,积分电荷法最为常用,其原理是通过测量在电容器上积累的热释电电荷,从而确定热释电系数…...
PostgreSQL——环境搭建
一、Linux # 安装 PostgreSQL 15 仓库 sudo dnf install -y https://download.postgresql.org/pub/repos/yum/reporpms/EL-$(rpm -E %{rhel})-x86_64/pgdg-redhat-repo-latest.noarch.rpm# 安装之前先确认是否已经存在PostgreSQL rpm -qa | grep postgres# 如果存在࿰…...
【学习笔记】erase 删除顺序迭代器后迭代器失效的解决方案
目录 使用 erase 返回值继续迭代使用索引进行遍历 我们知道类似 vector 的顺序迭代器被删除后,迭代器会失效,因为顺序迭代器在内存中是连续存储的,元素删除后,后续元素会前移。 但一些场景中,我们又需要在执行删除操作…...
给网站添加live2d看板娘
给网站添加live2d看板娘 参考文献: stevenjoezhang/live2d-widget: 把萌萌哒的看板娘抱回家 (ノ≧∇≦)ノ | Live2D widget for web platformEikanya/Live2d-model: Live2d model collectionzenghongtu/live2d-model-assets 前言 网站环境如下,文章也主…...
从“安全密码”到测试体系:Gitee Test 赋能关键领域软件质量保障
关键领域软件测试的"安全密码":Gitee Test如何破解行业痛点 在数字化浪潮席卷全球的今天,软件系统已成为国家关键领域的"神经中枢"。从国防军工到能源电力,从金融交易到交通管控,这些关乎国计民生的关键领域…...
CVPR2025重磅突破:AnomalyAny框架实现单样本生成逼真异常数据,破解视觉检测瓶颈!
本文介绍了一种名为AnomalyAny的创新框架,该方法利用Stable Diffusion的强大生成能力,仅需单个正常样本和文本描述,即可生成逼真且多样化的异常样本,有效解决了视觉异常检测中异常样本稀缺的难题,为工业质检、医疗影像…...
