【Java多线程】对线程池的理解并模拟实现线程池
目录
1、池
1.1、线程池
2、ThreadPoolExecutor 线程池类
3、Executors 工厂类
4、模拟实现线程池

1、池
“池”这个概念见到非常多,例如常量池、数据库连接池、线程池、进程池、内存池。
所谓“池”的概念就是:(提高效率)
1、提前把要用的对象准备好
2、用完的对象也不立即释放,留着以备下次使用。
从而大大降低了线程频繁地创建销毁造成的开销。
1.1、线程池
线程池也是如此,提前把要使用的线程,在线程池中准备好,等到需要用时就从池子里取
出,用完之后再归还给池子。
(其中取出和归还操作都是属于纯用户态代码,这就比内核操作更快,更可控)
上面提到了用户态,什么是用户态呢?
设想一个场景,你在银行柜台办理业务,该业务需要用到身份证复印件,此时有两种选择:一种是柜员拿着你的身份证帮你去复印,一种是你自己去复印。
显然自己去复印这个操作更加可靠,并且可控一些。如果交给柜员去复印,天知道柜员拿了你的身份证后还去做了什么,因为柜员本身需要处理的事情不止有帮你复印身份证这一件事,可能在帮你复印身份证的路上去做了别的事情,你能做的就只有在柜台前等柜员回来,这种操作显然更加不可控。
你自己去操作就相当于用户态,而柜员帮你操作就相当于是内核态。
而类比到计算机上简单来说就是:
如果一个任务,是在用户程序上完成的,就属于用户态,此时更加的可控。
如果一个任务,是通过系统申请创建线程,需要由内核来完成,就属于内核态,此时更加不可控。
2、ThreadPoolExecutor 线程池类
Java 在标准库中提供了 ThreadPoolExecutor 线程池类

- corePoolSize:核心线程数
- maximumPoolSize:最大线程数
- keepAliveTime:空闲时保持存活的时间(针对临时线程的)
- unit:存活时间的时间单位(s,min,ms,hour....)
- workQueue:阻塞队列,和定时器类似,线程池中也可以持有很多个任务
- threadFactory:线程工厂(这个类中的方法封装了 new Thread 的操作,同时给 Thread 设置了一些属性)
- handler:拒绝策略,当线程池中的阻塞队列满时,继续往队列中添加任务,此时线程池会执行什么样的操作就称为拒绝策略
针对拒绝策略,又分为四种:
1、继续添加任务直接拒绝接收并报错。【直接报错,新旧任务都不干了】
2、新的任务,由添加任务的线程负责执行。【谁揽的活儿谁干】
3、丢弃最旧的任务,新的添加进来。
4、丢弃新来的任务。

3、Executors 工厂类
ThreadPoolExecutor 本身用起来比较复杂,因此标准库还把 ThreadPoolExecutor 封装了一层,提供了另一个版本。
即 Executors 工厂类,通过这个类来创建出不同的线程池对象。
Executors 创建线程池的几种方式:
- newFixedThreadPool: 创建固定线程数的线程池
- newCachedThreadPool: 创建线程数目动态增长的线程池.
- newSingleThreadExecutor: 创建只包含单个线程的线程池.
- newScheduledThreadPool: 设定 延迟时间后执行命令,或者定期执行命令. 是进阶版的 Timer.
public class ExecutorDemo {public static void main(String[] args) {//将线程数设置为 10ExecutorService service = Executors.newFixedThreadPool(10);//使用 submit 方法向线程池中提交任务service.submit(new Runnable() {@Overridepublic void run() {System.out.println("hello Executors");}});}
}
既然 ThreadPoolExecutor 和 Executors 都可以创建线程池,那么到底该用哪个呢?
正常情况下直接使用 Executors 工厂类即可,当 Executors 工厂类提供的方法无法满足使用时,或者是想要高度定制化线程池时,才去使用 ThreadPoolExecutor。
4、模拟实现线程池
这里模拟写一个固定线程数目的线程池,即模拟使用 newFixedThreadPool 创建的线程池。
分析要点:
1、首先需要提供构造方法,方法中指定创建多少个线程
2、在构造方法中,把这些线程都创建好
3、用一个阻塞队列,将要执行的任务保存起来
4、提供 submit 方法,用于添加新的任务到阻塞队列中
public class MyThreadPoolExecutor {// 保存线程的集合private List<Thread> threadList = new ArrayList<>();// 保存任务的阻塞队列private BlockingQueue<Runnable> queue = new ArrayBlockingQueue<>(1000);public MyThreadPoolExecutor(int n) { //创建n个线程for (int i = 0; i < n; i++) {Thread t = new Thread(() -> {//这些线程需要做的就是不断从任务队列中取出任务并执行while (true) {try {// take 带有阻塞功能,为空时自动阻塞Runnable runnable = queue.take();runnable.run();} catch (InterruptedException e) {throw new RuntimeException(e);}}});//启动线程t.start();//将线程存入集合中,以备后续使用threadList.add(t);}}//submit 添加新的任务到队列中public void submit(Runnable runnable) throws InterruptedException {queue.put(runnable);}
}

【博主推荐】
【Java多线程】线程中几个常见的属性以及状态-CSDN博客
https://blog.csdn.net/zzzzzhxxx/article/details/136122127?spm=1001.2014.3001.5501【Java多线程】Thread类的基本用法-CSDN博客
https://blog.csdn.net/zzzzzhxxx/article/details/136121421?spm=1001.2014.3001.5501【Java多线程】对进程与线程的理解-CSDN博客
https://blog.csdn.net/zzzzzhxxx/article/details/136115808?spm=1001.2014.3001.5501
如果觉得作者写的不错,求给博主一个大大的点赞支持一下,你们的支持是我更新的最大动力!
如果觉得作者写的不错,求给博主一个大大的点赞支持一下,你们的支持是我更新的最大动力!
如果觉得作者写的不错,求给博主一个大大的点赞支持一下,你们的支持是我更新的最大动力!
相关文章:
【Java多线程】对线程池的理解并模拟实现线程池
目录 1、池 1.1、线程池 2、ThreadPoolExecutor 线程池类 3、Executors 工厂类 4、模拟实现线程池 1、池 “池”这个概念见到非常多,例如常量池、数据库连接池、线程池、进程池、内存池。 所谓“池”的概念就是:(提高效率) 1…...
python连接mysql数据库
连接MySQL数据库,通常我们会使用Python的mysql-connector-python库。下面是一个基本的示例来展示如何使用Python连接到MySQL数据库。 首先,确保你已经安装了mysql-connector-python库。如果没有,你可以使用pip来安装它: pip ins…...
docker用法
首先需要去docker官网注册你的账号,记住账号名称和密码; 然后在本地执行: docker login登录OK。 把ubuntu下载到本地: sudo docker pull ubuntusudo docker images输出: REPOSITORY TAG …...
DIcom调试Planar configuration
最近和CBCT组同事调dicom图像 这边得图像模块老不兼容对方得dicom文件。 vtk兼容,自己写得原生解析不兼容。 给对方调好了格式,下次生成文件还会有错。 简单记录下,日后备查。 今天对方又加了 个字段:Planar configuration 查…...
C#与VisionPro联合开发——跳转页面
1、跳转页面并打开相机 From1 所有代码展示 using System; using System.IO; using System.Windows.Forms; //引入VisionPro命名空间 using Cognex.VisionPro;namespace ConnectCamera {public partial class Form1 : Form {public Form1() {InitializeComponent();}CogAcqFif…...
服务端测试开发必备技能:Mock测试
什么是mock测试 Mock 测试就是在测试活动中,对于某些不容易构造或者不容易获取的数据/场景,用一个Mock对象来创建以便测试的测试方法。 Mock测试常见场景 无法控制第三方系统接口的返回,返回的数据不满足要求依赖的接口还未开发完成&#…...
vue3中ref创建变量取值时自动补充 .value 插件 volar
插件 TypeScript Vue Plugin (Volar) 设置中配置...
clickhouse的docker部署与springboot整合
注意:镜像bitnami/clickhouse包含服务端和客户端,yandex版本需要使用yandex/clickhouse-server,yandex/clickhouse-server docker启动命令(允许空密码 -e ALLOW_EMPTY_PASSWORD=yes),clickhouse版本不同,配置文件在的位置也会不一样/etc/clickhouse-server/config.xml d…...
Node.js_基础知识(计算机硬件基础)
主机的基本组成 CPU:Central Processing Unit,即中央处理器,是计算机的核心部件。是一块集成电路芯片,能够执行计算机指令并控制计算机的各种操作,负责运算和处理数据内存:是电脑硬件中的一块电路板,用于暂时存储CPU中的运算数据,是计算机与CPU进行沟通的桥梁,负责存储…...
git bash :download.sh: line 1: wget: command not found(已解决)
Windows中git bash完全可以替代原生的cmd,但是对于git bash会有一些Linux下广泛使用的命令的缺失,比如wget命令。 1、下载wget.exe,地址:https://eternallybored.org/misc/wget/ 2、将wget.exe 拷贝到C:\Program Files\Git\ming…...
BlackberryQ10 是可以安装 Android 4.3 应用的,Web UserAgent 版本信息
BlackberryQ10 是可以安装 Android 4.3 应用的 最近淘了个 Q10 手机,非常稀罕它,拿着手感一流。这么好的东西,就想给它装点东西,但目前所有的应用都已经抛弃这个安卓版本了。 一、开发环境介绍 BlackBerry Q10 的 安卓版本是 4.…...
JS前端高频面试
JS数据类型有哪些,区别是什么 js数据类型分为原始数据类型和引用数据类型。 原始数据类型包括:number,string,boolean,null,undefined,和es6新增的两种类型:bigint 和 symbol。&am…...
Flask数据库操作-Flask-SQLAlchemy
Flask中一般使用flask-sqlalchemy来操作数据库。flask-sqlalchemy的使用介绍如下: 一、SQLAlchemy SQLALchemy 实际上是对数据库的抽象,让开发者不用直接和 SQL 语句打交道,而是通过 Python 对象来操作数据库,在舍弃一些性能开销…...
H5获取手机相机或相册图片两种方式-Android通过webview传递多张照片给H5
需求目的: 手机机通过webView展示H5网页,在特殊场景下,需要使用相机拍照或者从相册获取照片,上传后台。 完整流程效果: 如下图 一、H5界面样例代码 使用html文件格式,文件直接打开就可以展示布局&#…...
mysql进阶学习 | DAY 14
存储引擎 体系结构 连接层 服务层 引擎层 存储层 存储引擎 表类型 查看引擎 查看建表语句 指定存储引擎 ENGINE SHOW engins InnoDB 默认存储引擎 遵循ACID模型 支持事务 行级锁 提高并发访问性能 支持外键 FOREIGN KEY约束 保证数据完整性和正确性 对应文件 xx…...
使用GPT生成python图表
首先,生成一脚本,读取到所需的excel表格 import xlrddata xlrd.open_workbook(xxxx.xls) # 打开xls文件 table data.sheet_by_index(0) # 通过索引获取表格# 初始化奖项字典 awards_dict {"一等奖": 0,"二等奖": 0,"三等…...
[深度学习]yolov9+deepsort+pyqt5实现目标追踪
【YOLOv9DeepSORTPyQt5追踪介绍】 随着人工智能技术的飞速发展,目标追踪在视频监控、自动驾驶等领域的应用日益广泛。其中,YOLOv9作为先进的目标检测算法,结合DeepSORT多目标追踪算法和PyQt5图形界面库,能够为用户提供高效、直观…...
C#_WaitAll、WhenAll、async及await
Task.WhenAll、Task.WaitAll Task.WhenAll 和 Task.WaitAll 都是用于等待多个任务完成的方法,但它们之间有一些重要的区别。 返回类型: Task.WhenAll: 返回一个 Task 对象,该对象表示所有输入任务的联合任务。 Task.WaitAll: 没有返回值。它是一个同步方…...
leetcode hot100零钱兑换Ⅱ
本题可以看出也是背包问题,但区别于之前的01背包问题,这个是完全背包问题的变形形式。 下面介绍01背包和完全背包的区别与联系: 01背包是背包中的物品只能用一次,不可以重复使用,而完全背包则是可以重复使用。01/完全…...
路由器配置DMZ主机映射
路由器配置DMZ主机映射 光猫路由模式配置方法 光猫路由模式是用光猫进行拨号连接,所有设备通过光猫访问互联网,只需要设置光猫的DMZ主机映射地址为局域网主机即可 光猫桥接模式配置方法 光猫桥接模式,是穿透光猫,通过路由器拨…...
GPON OMCI抓包避坑指南:Wireshark插件版本、芯片指令与实战解析全流程
GPON OMCI抓包避坑指南:Wireshark插件版本、芯片指令与实战解析全流程 在GPON网络运维和研发过程中,OMCI(ONU Management and Control Interface)协议分析是定位问题的关键手段。但许多工程师在实际操作中常陷入版本兼容性陷阱、芯…...
别再手动飞了!用Python脚本一键操控AirSim无人机,实现自动巡航与悬停
用Python脚本全自动操控AirSim无人机:从基础巡航到复杂航线规划 在无人机仿真测试和算法开发中,手动控制不仅效率低下,更难以保证飞行动作的精确性和可重复性。想象一下,当你需要测试一个新型避障算法,或者采集特定飞行…...
避坑指南:LangChain中create_retrieval_chain与JinaEmbeddings的最佳实践
LangChain与JinaEmbeddings深度整合:从避坑到性能优化的全流程指南 在构建基于大语言模型的检索增强生成(RAG)系统时,LangChain框架与JinaEmbeddings的组合已经成为许多开发者的首选方案。这种技术组合既能利用LangChain强大的流程编排能力,…...
PostgreSQL实战:使用pg_dump精准导出特定模式下的表结构
1. 为什么需要精准导出特定模式下的表结构 在实际的数据库管理工作中,我们经常会遇到只需要导出特定模式(schema)下表结构的需求。比如在微服务架构中,每个服务可能对应数据库中的一个模式;或者在进行数据库迁移时&…...
用AI看牙新姿势:5张手机照片,TeethDreamer帮你生成3D牙齿模型(附保姆级复现思路)
从5张照片到3D牙齿模型:TeethDreamer技术全解析与实战指南 想象一下,你只需要用手机拍摄5张口腔照片,就能生成一个精确的3D牙齿模型——这不再是科幻电影中的场景。TeethDreamer作为2024年MICCAI会议上的突破性研究,将扩散模型与3…...
FastAPI负载测试:持续集成的完整指南
FastAPI负载测试:持续集成的完整指南 【免费下载链接】fastapi FastAPI framework, high performance, easy to learn, fast to code, ready for production 项目地址: https://gitcode.com/GitHub_Trending/fa/fastapi FastAPI作为高性能、易学习的现代Pyth…...
终极指南:如何用Muzic的MusicBERT实现符号音乐深度理解(从入门到实践)
终极指南:如何用Muzic的MusicBERT实现符号音乐深度理解(从入门到实践) 【免费下载链接】muzic 这是一个微软研究院开发的音乐生成AI项目。适合对音乐、音频处理以及AI应用感兴趣的开发者、学生和研究者。特点是使用深度学习技术生成音乐&…...
DownKyi:B站视频高效解决方案——如何三步搞定8K资源本地化管理
DownKyi:B站视频高效解决方案——如何三步搞定8K资源本地化管理 【免费下载链接】downkyi 哔哩下载姬downkyi,哔哩哔哩网站视频下载工具,支持批量下载,支持8K、HDR、杜比视界,提供工具箱(音视频提取、去水印…...
Python内存暴涨突然崩溃?3个被90%开发者忽略的GC调优关键点揭秘
第一章:Python内存暴涨与崩溃的典型现象诊断当Python程序在运行中突然响应迟缓、频繁触发MemoryError,或进程被操作系统强制终止(如Linux下收到SIGKILL (9)),往往标志着内存使用已严重失控。这类问题通常不会立即暴露&…...
别让你的 Coding Agent 瞎忙活,你最缺的可能是这套 Harness 规则
别让你的 Coding Agent 瞎忙活,你最缺的可能是这套 Harness 规则 团队把 Claude Code、Codex、Cursor 这类工具接进日常开发后,最先暴露出的瓶颈通常在协作环节。 一个简单的 bug fix 任务,agent 可能会扩出十几个文件的改动。 跑了一行测试…...
