【多线程】深入剖析线程池的应用

💐个人主页:初晴~
📚相关专栏:多线程 / javaEE初阶
还记得我们一开始引入线程的概念,就是因为进程太“重”了,频繁创建销毁进程的开销是非常大的。而随着计算机的发展,业务上对性能的要求越来越高,导致线程的创建/销毁频次也越来越高,频繁创建/销毁线程的开销也会非常大了,会开始明显影响性能了。为了缓解这一问题,就发展出了“线程池”这一结构。那么,线程池具体是如何实现的,又该如何应用呢?就让博主带大家好好梳理一下吧。
一、何为线程池
让我们先来看一下这个场景:
肯德基要实现外卖业务“宅急送”,可以有两种实现方式:
第一种方式:每次收到一个顾客的订单,就临时聘用一个配送员完成这单外卖的配送,配送完成之后就当场解雇这个配送员,并结算工资。
第二种方式:提前聘用几个配送员,每收到一个顾客的订单,就将其分配给一名空闲的配送员去完成配送,在配送完成后并不会直接解雇,而是会等待其它订单继续配送。当实在发现没有订单时,才把这几个配送员解雇了
由于聘用和解雇配送员的操作都比较繁琐,像第一种方法就会频繁执行这两个操作,效率很低。而方法二则提前雇用好了几个配送员,且中途配送需求都交给他们来处理,极大地减少了雇用和解雇操作的次数,明显提高了效率。
线程池亦是如此,它预先创建了一组可重用的线程,当有新的任务提交给线程池时,线程池就会从池中取出一个空闲的线程来执行这个任务;而当线程完成任务后,它并不会被销毁,而是再次返回到线程池中等待下一个任务。从而大幅提高线程利用率,提升效率。
优点:
- 资源重用:避免频繁创建和销毁线程带来的开销,因为创建和销毁线程是比较耗时的操作。
- 提高响应速度:当任务到达时,线程池可以快速分配已有线程进行处理,而不需要等待新线程的创建。
- 控制资源消耗:通过限制最大线程数量来控制资源的消耗,防止过多的线程同时运行而导致系统资源枯竭。
- 有效控制线程生命周期:线程池可以对线程进行统一管理,包括线程的创建、分配、回收等。
- 简化线程管理:线程池提供了一种机制,使得线程管理变得更加简单和高效。
二、标准库中的线程池
在Java中,线程池是由java.util.concurrent包下的几个类来实现的,主要包括:
- Executor:这是最基础的接口,定义了执行任务的方法。
- ExecutorService:扩展了Executor接口,提供了更多的管理方法,如启动、关闭线程池等。
- ThreadPoolExecutor:实现了ExecutorService接口,提供了更详细的线程池配置和管理方法。
- Executors:这是一个工具类,提供了创建不同类型的线程池的工厂方法。
我们接下来就先来介绍一下ThreadPoolExecutor类的构造方法吧:

参数含义:
- int corePoolSize :核心线程数
- int maximumPoolSize :最大线程数,即核心线程数与非核心线程数之和
- long keepAliveTime :非核心线程在线程空闲时最大存活时间,超过这个时间就会被销毁
- TimeUnit unit :最大存活时间的单位(秒,分钟,小时,天……)
- BlockingQueue<Runnable> workQueue :工作队列,使用者通过类似“submit”的等待,把要执行的任务设定到线程池内,让线程池内部的工作线程负责执行这些任务
- ThreadFactory threadFactory :线程工厂,就是Thread 类的工厂类,通过这个类,完成Thread类的实例创建和初始化操作。可以针对线程池中的线程进行批量的设置属性
- RejectedExecutionHandler handler :拒绝策略,如果线程池队列满了,依然继续往队列中添加任务,不要阻塞,而是通过各种拒绝策略来处理。
java标准库给出了四种拒绝策略:

但是由以上介绍我们可以看出,虽然ThreadPoolExecutor类的功能很强大,但使用很麻烦。为了使用更加便利,标准库又对这个类进行了封装,让Executors类提供了一些工厂方法,可以更方便地构造出线程池。一些工厂方法简介:

简单应用:
public class Main {public static void main(String[] args) {ExecutorService service= Executors.newFixedThreadPool(4);for(int i=0;i<100;i++){int id=i;service.submit(()->{Thread current=Thread.currentThread();System.out.println("hello world "+id+","+current.getName());});}}
}

但是我们发现这个代码执行后,虽然100个任务都执行完毕了,但是整个进程却没有结束,这时为什么呢?因为线程池创建出来的线程默认是“前台线程”,即使 main 线程结束了,线程池里的前台线程也会仍然存在,导致进程并不会结束。
我们可以利用“shutdown()方法”来强制终止线程池中的所有线程:

这回进程就能正常结束了

注意:
在使用线程池时,需要指定线程个数,这个值并没有统一的规范,最好通过“实验”的方法,给线程池设置不同数,再分别进行性能测试,然后分析响应时间/消耗资源等指标来挑选一个合适的值,这样才是最好的
三、线程池的实现
我们这里就试着实现一下简单的固定线程数目的线程吧。
class MyThreadPool{private BlockingQueue<Runnable> queue=new ArrayBlockingQueue<>(1000);private volatile Boolean isAlive=true;public MyThreadPool(int n){for(int i=0;i<n;i++){Thread t=new Thread(()->{while(isAlive){try {Runnable runnable=queue.take();runnable.run();} catch (InterruptedException e) {throw new RuntimeException(e);}}});t.start();}}//添加任务public void submit(Runnable runnable){try {queue.put(runnable);} catch (InterruptedException e) {throw new RuntimeException(e);}}public void shutdown(){isAlive=false;}
}
public class Main {public static void main(String[] args) throws InterruptedException {MyThreadPool myThreadPool=new MyThreadPool(4);for (int i = 0; i < 100; i++) {int id=i;myThreadPool.submit(()->{System.out.println("执行任务"+id+", "+Thread.currentThread().getName());});}Thread.sleep(1000);myThreadPool.shutdown();}
}

那么本篇文章就到此为止了,如果觉得这篇文章对你有帮助的话,可以点一下关注和点赞来支持作者哦。作者还是一个萌新,如果有什么讲的不对的地方欢迎在评论区指出,希望能够和你们一起进步✊

相关文章:
【多线程】深入剖析线程池的应用
💐个人主页:初晴~ 📚相关专栏:多线程 / javaEE初阶 还记得我们一开始引入线程的概念,就是因为进程太“重”了,频繁创建销毁进程的开销是非常大的。而随着计算机的发展,业务上对性能的要求越来越…...
『功能项目』切换职业面板【48】
我们打开上一篇47技能冷却蒙版的项目, 本章要做的事情是切换职业UI面板的功能 首先双击打开Canvas预制体在左上主角面板信息中新建一个button按钮 重命名(父物体是按钮Button,子物体Image即可) 创建一个Image 设计一下布局 复制三…...
【EasyExcel】@ColumnWidth(value = 20) EasyExcel设置列宽不生效
经过测试发现,只有XLS,ColumnWidth注解才会生效,选择CSV和XLSX都不会生效 //对应的导出实体类 EasyExcel.write(outputStream, Result.class)//excel文件类型,包括CSV、XLS、XLSX.excelType(ExcelTypeEnum.XLS)...
CPU 和 GPU:为什么GPU更适合深度学习?
目录 什么是 CPU ? 什么是 GPU ? GPU vs CPU 差异性对比分析 GPU 是如何工作的 ? GPU 与 CPU 是如何协同工作的 ? GPU vs CPU 类型解析 GPU 应用于深度学习 什么是 CPU ? CPU(中央处理器)…...
【机器学习】:解锁数据背后的智慧宝藏——深度探索与未来展望
欢迎来到 破晓的历程的 博客 ⛺️不负时光,不负己✈️ 文章目录 引言一、深入机器学习的内在机制二、最新进展与趋势三、对未来社会的深远影响结语 引言 在上一篇博客中,我们初步探讨了机器学习如何成为解锁数据背后智慧的关键工具。现在,让…...
【Kubernetes】常见面试题汇总(十八)
目录 55.简述 Kubernetes 共享存储的作用? 56.简述 Kubernetes 数据持久化的方式有哪些? 57.简述 Kubernetes PV 和 PVC ? 58.简述 Kubernetes PV 生命周期内的阶段? 55.简述 Kubernetes 共享存储的作用? Kubernet…...
无限边界:现代整合安全如何保护云
尽管云计算和远程工作得到广泛采用,零信任网络也稳步推广,但边界远未消失。相反,它已被重新定义。就像数学分形的边界一样,现代网络边界现在无限延伸到任何地方。 不幸的是,传统工具在现代无限边界中效果不佳。现代边…...
HTML贪吃蛇游戏
文章目录 贪吃蛇游戏 运行效果代码 贪吃蛇游戏 贪吃蛇是一款经典的休闲益智游戏。本文将通过HTML5和JavaScript详细解析如何实现一个简易版的贪吃蛇游戏。游戏的主要逻辑包括蛇的移动、碰撞检测、食物生成等功能。以下是游戏的完整代码及注释解析。(纯属好玩&#…...
HTML 揭秘:HTML 编码快速入门
HTML 揭秘:HTML 编码快速入门 一 . 前端知识介绍二 . HTML 介绍三 . HTML 快速入门四 . HTML 编辑器 - VSCode4.1 插件安装4.2 修改主题配色4.3 修改快捷键4.4 设置自动保存4.5 创建 HTML 文件4.5 书写 HTML 代码4.6 常见快捷键 五 . 基础标签5.1 字体标签5.1.1 col…...
Ubuntu22.04系统安装opencv步骤简述及问题解决方法
前言 opencv是一个功能强大、开源且跨平台的计算机视觉库,适用于多种编程语言和操作系统,能够帮助开发者构建各种视觉项目。其模块众多,提供了诸多功能,能够进行图像处理、视频处理等等。比如:Highgui模块提供图像用户…...
移情别恋c++ ദ്ദി˶ー̀֊ー́ ) ——13.mapset
1. 关联式容器 在初阶阶段,我们已经接触过STL中的部分容器,比如:vector、list、deque、 forward_list(C11)等,这些容器统称为序列式容器,因为其底层为线性序列的数据结构,里面 存储的是元素本身。那什么是关…...
【webpack4系列】webpack基础用法(二)
文章目录 entryoutputloaderpluginmode前端构建基础配置关联HTML插件html-webpack-plugin构建 CSS 解析 ES6和React JSX解析 ES6解析 React JSX 解析CSS、Less和Sass解析CSS解析Less解析sass 解析图片和字体资源解析:解析图片资源解析:解析字体资源解析&…...
Python Pyvis库创建交互式网络图 高级功能详解
文章目录 动态网络图图布局调整扩展到大规模网络动态网络图 Pyvis支持创建动态网络图,通过时间轴展示网络图的演化过程。 需要使用set_options函数,参数必须为json格式。动态网络图支持添加点和边。 下面是一个简单的动态网络图示例: # 动态网络图示例 from pyvis.networ…...
Linux服务器上安装git lfs命令
有时候,需要批量下载数据集时要用到git lfs命令 首先,使用pip install git-lfs安装,会发现使用时仍然提示:git: lfs is not a git command. See git --help. 这就意味着安装不成功。 因此,需要通过如下途径手动安装&a…...
S100A9:鸡支原体感染中的免疫调控“双面间谍”【AbMole】
在生物学研究的广阔天地里,总有一些分子扮演着令人意想不到的角色。今天,我们要探索的主角是S100A9蛋白,一种在鸡支原体感染过程中展现出惊人双重功能的分子。这项来自华中农业大学动物科技学院与兽医学院的最新研究成果,揭示了S1…...
黑神话悟空黑风山攻略
在黑神话悟空中,玩家一开始来到黑风山的地图就会站在前山土地庙。 下面小编将会根据黑风山地图的地标来进行路线攻略推荐, 玩家可以一边查看游戏地图一边了解这些路线的动线是怎样的。 在苍狼林前山捡到药材老山参,跟随金色光线找到附近的土…...
Android 11 FileProvider的使用和限制
概述: 从Android 7开始,将不允许在app之间,使用file uri,即file://的方式,传递一个file,否则会抛出异常:FileUriExposedException ,其解决方案,就是使用FileProvider,用c…...
闭包+面试真题
对闭包的理解 闭包是内层函数使用外层变量 (子级可以访问父级的变量,但是父级不可以访问子级的) 闭包是指有权访问另一个函数作用域中变量的函数,创建闭包的最常见的方式就是在一个函数内创建另一个函数,创建的函数可以访问到当前函数的局部…...
Java企业面试题3
1. break和continue的作用(智*图) break:用于完全退出一个循环(如 for, while)或一个 switch 语句。当在循环体内遇到 break 语句时,程序会立即跳出当前循环体,继续执行循环之后的代码。continue:用于跳过…...
第3章C/C++流程控制
第3章C/C流程控制 循环语句for循环语句【例题3.14】 求123....100。使用for语句实现循环。【例题3.15】 打印出所有“水仙花数”。【例题3.16】 输出一个金字塔图形。 跳转语句break语句【3.20】输入若干个整数,计算已输入整数之和,直到输入负数为止。 c…...
LBE-LEX系列工业语音播放器|预警播报器|喇叭蜂鸣器的上位机配置操作说明
LBE-LEX系列工业语音播放器|预警播报器|喇叭蜂鸣器专为工业环境精心打造,完美适配AGV和无人叉车。同时,集成以太网与语音合成技术,为各类高级系统(如MES、调度系统、库位管理、立库等)提供高效便捷的语音交互体验。 L…...
C++:std::is_convertible
C++标志库中提供is_convertible,可以测试一种类型是否可以转换为另一只类型: template <class From, class To> struct is_convertible; 使用举例: #include <iostream> #include <string>using namespace std;struct A { }; struct B : A { };int main…...
基于服务器使用 apt 安装、配置 Nginx
🧾 一、查看可安装的 Nginx 版本 首先,你可以运行以下命令查看可用版本: apt-cache madison nginx-core输出示例: nginx-core | 1.18.0-6ubuntu14.6 | http://archive.ubuntu.com/ubuntu focal-updates/main amd64 Packages ng…...
高等数学(下)题型笔记(八)空间解析几何与向量代数
目录 0 前言 1 向量的点乘 1.1 基本公式 1.2 例题 2 向量的叉乘 2.1 基础知识 2.2 例题 3 空间平面方程 3.1 基础知识 3.2 例题 4 空间直线方程 4.1 基础知识 4.2 例题 5 旋转曲面及其方程 5.1 基础知识 5.2 例题 6 空间曲面的法线与切平面 6.1 基础知识 6.2…...
高防服务器能够抵御哪些网络攻击呢?
高防服务器作为一种有着高度防御能力的服务器,可以帮助网站应对分布式拒绝服务攻击,有效识别和清理一些恶意的网络流量,为用户提供安全且稳定的网络环境,那么,高防服务器一般都可以抵御哪些网络攻击呢?下面…...
基于matlab策略迭代和值迭代法的动态规划
经典的基于策略迭代和值迭代法的动态规划matlab代码,实现机器人的最优运输 Dynamic-Programming-master/Environment.pdf , 104724 Dynamic-Programming-master/README.md , 506 Dynamic-Programming-master/generalizedPolicyIteration.m , 1970 Dynamic-Programm…...
虚拟电厂发展三大趋势:市场化、技术主导、车网互联
市场化:从政策驱动到多元盈利 政策全面赋能 2025年4月,国家发改委、能源局发布《关于加快推进虚拟电厂发展的指导意见》,首次明确虚拟电厂为“独立市场主体”,提出硬性目标:2027年全国调节能力≥2000万千瓦࿰…...
tomcat指定使用的jdk版本
说明 有时候需要对tomcat配置指定的jdk版本号,此时,我们可以通过以下方式进行配置 设置方式 找到tomcat的bin目录中的setclasspath.bat。如果是linux系统则是setclasspath.sh set JAVA_HOMEC:\Program Files\Java\jdk8 set JRE_HOMEC:\Program Files…...
第一篇:Liunx环境下搭建PaddlePaddle 3.0基础环境(Liunx Centos8.5安装Python3.10+pip3.10)
第一篇:Liunx环境下搭建PaddlePaddle 3.0基础环境(Liunx Centos8.5安装Python3.10pip3.10) 一:前言二:安装编译依赖二:安装Python3.10三:安装PIP3.10四:安装Paddlepaddle基础框架4.1…...
Windows电脑能装鸿蒙吗_Windows电脑体验鸿蒙电脑操作系统教程
鸿蒙电脑版操作系统来了,很多小伙伴想体验鸿蒙电脑版操作系统,可惜,鸿蒙系统并不支持你正在使用的传统的电脑来安装。不过可以通过可以使用华为官方提供的虚拟机,来体验大家心心念念的鸿蒙系统啦!注意:虚拟…...
