Java并发编程之线程池详解
目录
🐳今日良言:不悲伤 不彷徨 有风听风 有雨看雨
🐇一、简介
🐇二、相关代码
🐼1.线程池代码
🐼2.自定义实现线程池
🐇三、ThreadPoolExecutor类
🐳今日良言:不悲伤 不彷徨 有风听风 有雨看雨

🐇一、简介
首先来介绍一下什么是线程池,线程池是一种利用池化技术思想来实现的线程管理技术,主要是为了复用线程、便利地管理线程和任务并将线程的创建和任务的执行解耦开来。我们可以创建线程池来复用已经创建的线程来降低频繁创建和销毁线程所带来的资源消耗。在JAVA中主要是通过java.util.concurrent包中的ThreadPoolExecutor类来实现线程池 。
🐇二、相关代码
🐼1.线程池代码

这里就是创造出一个10个线程的线程池,然后就可以随机安排这些线程完成任务了。
线程池提供了一个重要的方法 submit 可以给线程池提交若干个任务。

submit的参数是一个Runnable,用来描述这些线程要执行的任务是什么。
线程池中的线程都是前台线程,前台线程会阻止进程结束,也就是说,运行程序之后,main线程结束了,但是整个进程没有结束。

当前是往线程池里放了 1000 个任务,1000 个任务就是由这 10 个线程来平均分配一下,差不多是一人执行 100个,但是这里并非是严格的平均,可能有的多一个有的少一个都正常。(每个线程都执行完一个任务之后,再立即取下一个任务...由于每个任务执行时间都差不多,因此每个线程做的任务数量就差不多)
上述代码涉及到变量捕获

这里的 i 是主线程里的局部变量(在主线程的栈上),随着主线程的代码执行结束就销毁了,但是,很可能这里的 for 循环已经执行完了,当前 run 的任务在线程池里还没有排到,此时 i 就已经要销毁了。这里的 run 方法属于 Runnable ,这个方法的执行时机并不是立刻执行,而是在未来的某个时间点(后续在线程池的队列中排到了) 才会执行,为了避免作用域的差异,导致执行 run 方法的时候,i 已经销毁了,于是就有了变量捕获,也就是让 run 方法把主线程的 i 往当前 run 方法的栈上拷贝一份(在定义 run 方法的时候了,把当前 i 的值记住,后续执行 run 的时候,就创建一个也叫做 i 的局部变量,并且把这个值给赋值过去)。
在Java 中,对于变量捕获,做了一些额外的要求,在JDK 1.8之前,要求变量捕获只能捕获 final 修饰的变量,后来发现,这样太麻烦了,于是,在 JDK 1.8 开始,发送了一点标准,要求不一定非得待 final 关键字,只要代码中没有修改过这个变量,也可以捕获。
在上述代码中,i 是被修改的,因此不能捕获,但是 n 没有被修改,所以可以被捕获。
接下来,介绍一下几种不同的线程池:

new FixedThreadPool 创建固定线程数的线程池。
newCachedThreadPool 线程数量是动态变化的,任务多了就多创建几个线程,任务少了
就少创建几个。
newScheduledThreadPool 类似于定时器,让任务延时执行。
newSingleThreadExecutor 线程池里只有一个线程。
上述这些线程池,本质上都是通过包装 ThreadPoolExecutor 来实现的,这个线程池用起来比较麻烦,所以提供了工厂类,让我们使用更方便,ThreadPoolExecutor 提供的功能更为强大,后面会详细介绍。
🐼2.自定义实现线程池
自定义实现线程池代码如下:
import java.util.concurrent.BlockingQueue;
import java.util.concurrent.LinkedBlockingQueue;class MyThreadPool {// 阻塞队列private BlockingQueue<Runnable> queue = new LinkedBlockingQueue<>();// 若干个工作线程// n表示线程的数量public MyThreadPool(int n) {for (int i = 0; i < n; i++) {Thread t = new Thread(() -> {while (true) {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 class Exercise{public static void main(String[] args) {MyThreadPool myThreadPool = new MyThreadPool(10);for (int i = 0; i < 1000; i++) {int n = i;myThreadPool.submit(new Runnable() {@Overridepublic void run() {System.out.println("hello:"+n);}});}}
}
🐇三、ThreadPoolExecutor类
最后,介绍一下ThreadPoolExecutor 里面的参数,如下图:

1)int corePoolSize
核心线程数
2)int maximumPoolSize
最大线程数
ThreadPoolExecutor 相当于是把里面的线程分成了两类,一类是核心线程,一类是临时线程,核心线程相当于是正式工,临时线程相当于是临时工,这二者之和就是最大线程数。
如果任务多,需要创建更多的线程,但是,一个程序的任务不一定始终都有很多,有时候多,有时候少,如果现在任务少了,线程还那么多,就非常不合适了,因此,就需要对现有的线程进行一定的淘汰,整体的淘汰策略是:核心线程保底,临时线程动态调节。
在实际开发的时候,线程池的线程数设置成多少比较合适呢?
实际上,这里不应该回答出具体的数字,在实际开发中,线程池的线程数设置需要根据具体情况进行调整,一般来说,应该设置为CPU核心数的两倍到四倍之间,如果线程数过少,则导致任务等待时间过长,而如果线程数过多,会导致系统资源浪费。如果任务是IO密集型的,那么可以适当的增加线程数,如果任务是CPU密集型的,则可以适当的减少线程数。
3)long keepAliveTime
临时线程的最大空闲时间,超出这个时间,临时线程就会被销毁了。
也就是临时工的最大摸鱼时间。
4)TimeUnit unit
时间单位(s,ms,分钟...)
5)BlockingQueue<Runnable> workQueue
线程池的任务队列
此处使用的是阻塞队列,每个线程都是在不停的尝试take,如果有任务,就take成功,没有就阻塞。
6)ThreadFactory threadFactory
用于创建线程,线程池是需要创建线程的
7)RejectedExecutionHandler handler
描述了线程池的“拒绝策略”,也是一个特殊的对象,描述了当线程池任务队列满了,如果继续添加任务会有什么样的行为。
标准库提供了四个拒绝策略,如下图:
第一个拒绝策略
如果任务太多,任务队列满了,就直接抛出异常。
第二个拒绝策略
如果任务太多,任务队列满了,多出来的任务,谁加的谁负责执行。
第三个拒绝策略
如果任务太多,任务队列满了,丢弃最早的任务。
第四个拒绝策略
如果任务太多,任务队列满了,丢弃最新的任务。
以上就是本篇博客的所有内容了,望有所帮助~
相关文章:
Java并发编程之线程池详解
目录 🐳今日良言:不悲伤 不彷徨 有风听风 有雨看雨 🐇一、简介 🐇二、相关代码 🐼1.线程池代码 🐼2.自定义实现线程池 🐇三、ThreadPoolExecutor类 🐳今日良言:不悲伤 不彷徨 有风听风 有…...
开源数据库Mysql_DBA运维实战 (总结)
开源数据库Mysql_DBA运维实战 (总结) SQL语句都包含哪些类型 DDL DCL DML DQL Yum 安装MySQL的配置文件 配置文件:/etc/my.cnf日志目录:/var/log/mysqld.log错误日志:/var/log/mysql/error.log MySQL的主从切换 查看主…...
图神经网络与分子表征:1. 分子图和图神经网络基础
CSDN的朋友们大家好,好久没写系列文章了。 近期读了很多图神经网络(GNN)和分子表征(molecular representation)的论文,正好最近不是很忙,所以我决定把自己的学习过程记录下来,与大家…...
Spring Boot与Redisson的整合。分布式锁
Spring Boot与Redisson的整合可以帮助您在Spring Boot应用程序中使用分布式锁、缓存等功能。下面是一些基本步骤来整合Spring Boot与Redisson: 添加Maven/Gradle依赖: 在您的Spring Boot项目的pom.xml(Maven)或build.gradle&#…...
Lua中逻辑运算符and,or,not 区别与用法
在Lua中,逻辑运算符包括 and、or 和 not。它们用于对布尔值进行逻辑运算。 and运算符: 当同时满足两个表达式时,返回第二个表达式的值;否则,返回第一个表达式的值。如果第一个表 达式的值为false或nil,则…...
使用 spaCy 增强 NLP 管道
介绍 spaCy 是一个用于自然语言处理 (NLP) 的 Python 库。SpaCy 的 NLP 管道是免费且开源的。开发人员使用它来创建信息提取和自然语言理解系统,例如 Cython。使用该工具进行生产,拥有简洁且用户友好的 API。 如果您处理大量文本,您会想了解更多相关信息。例如,它是关于什…...
【HCIP】08.ISIS中间系统
链路状态协议,传递LSA信息ISIS基于数据链路层封装在OSI时,也有自己的网络层地址和自己的路由协议,即ISIS。之前的ISIS支持OSI的网络层地址,是为OSI中的CLNP(无连接网络协议)网络设计的路由协议,…...
Android 13 Framework 添加自定义的系统服务CustomService
目的: 添加自定义的系统服务,在自定义的服务中开发定制的API接口和功能,独立于系统核心服务,方便开发和维护。 开发环境:Android 13 MTK平台 涉及修改的文件如下 device/mediatek/sepolicy/base/private/service_contexts device/mediatek/sepolicy/base/vendor/platfo…...
前端食堂技术周刊第 95 期:Fresh 1.4、Rollup 迁移至 SWC计划、RSC Devtools、使用开源库的边界、AI 帮你讲论文
美味值:🌟🌟🌟🌟🌟 口味:冰葡美式 食堂技术周刊仓库地址:https://github.com/Geekhyt/weekly 大家好,我是童欧巴。欢迎来到前端食堂技术周刊,我们先来看下…...
【TypeScript】枚举类型
在 TypeScript 中,枚举(Enum)是一种用于定义命名常量集合的数据类型。枚举使代码更加可读和可维护,因为它们为一组具有语义的值提供了命名。 以下是 TypeScript 中枚举的基本用法和特点: // 声明一个枚举 enum Direc…...
快速通过华为HCIP认证
你可以按照以下步骤进行准备和学习: 华为认证课程和资料--提取码:1234https://pan.baidu.com/s/1YJhD8QbocHhZ30MvrKm8hg 了解认证要求:查看华为官方网站上的HCIP认证要求和考试大纲,了解考试的内容、考试形式和考试要求。 学习相关知识&am…...
派森 #P124. 公式计算
描述 输入数正整数m,输出0! 1! ...m!的计算结果。 样例 输入 5 输出 154 代码: m int(input()) result 1 factorial 1 for i in range(1, m 1):factorial * iresult factorial print(result) # 法2def factorial(n):"""计…...
opencv进阶14-Harris角点检测-cv2.cornerHarris
类似于人的眼睛和大脑,OpenCV可以检测图像的主要特征并将这 些特征提取到所谓的图像描述符中。然后,可以将这些特征作为数据 库,支持基于图像的搜索。此外,我们可以使用关键点将图像拼接起 来,组成更大的图像。&#x…...
JVM中对象和GC Root之间的四种引用关系
1. 强引用 只有所有 GC Roots 对象都不通过【强引用】引用该对象,该对象才能被垃圾回收 由GC Root直接new出来的对象是强引用,只有当GC Root不再引用该对象的时候,才会被回收 例子: List<String> list new ArrayList<&…...
【李宏毅机器学习】注意力机制
输出 我们会遇到不同的任务,针对输出的不一样,我们对任务进行划分 给多少输出多少 给一堆向量,输出一个label,比如说情感分析 还有一种任务是由机器决定的要输出多少个label,seq2seq的任务就是这种,翻译也…...
Nginx使用keepalived配置VIP
VIP常用于负载均衡的高可用,使用VIP可以给多个主机绑定一个IP,这样,当某个负载应用挂了之后,可以自动切到另一个负载。 我这里是在k8s环境中做的测试,集群中有6个节点,我给140和141两个节点配置VIP。 1. 安…...
C语言编写图形界面
文章目录 环境使用库基础概念句柄 程序的入口创建窗口定义窗口类注册窗口类创建窗口 完整代码运行效果 环境 使用的是VSCode MinGW; 使用库 我们使用windows.h库来实现图形化界面。 头文件如下: #include <windows.h>windows.h是 Windows 操作…...
K8s学习笔记3
Kubernetes功能: Kubernetes是一个轻便的可扩展的开源平台,用于管理容器化应用和服务。通过Kubernetes能够进行应用的自动化部署和扩缩容。在Kubernetes中,会将组成应用的容器组合成一个逻辑单元以更易管理和发现。Kubernetes积累了作为Goog…...
ceph集群的扩容缩容
文章目录 集群扩容添加osd使用ceph-deploy工具手动添加 添加节点新节点前期准备新节点安装ceph,出现版本冲突 ceph-deploy增加节点 集群缩容删除osd删除节点 添加monitor节点删除monitor节点使用ceph-deploy卸载集群 实验所用虚拟机均为Centos 7.6系统,8…...
gremlin安装使用 详细步骤
gremlin是一个图数据库查询工具,注意他只是一个工具类似于dbeaver,navicat,sqlyog,是专门来分析图数据库的一个工具。 下载 下载地址Apache Download Mirrors 省事的可以直接 wget https://www.apache.org/dyn/closer.lua/tin…...
第19节 Node.js Express 框架
Express 是一个为Node.js设计的web开发框架,它基于nodejs平台。 Express 简介 Express是一个简洁而灵活的node.js Web应用框架, 提供了一系列强大特性帮助你创建各种Web应用,和丰富的HTTP工具。 使用Express可以快速地搭建一个完整功能的网站。 Expre…...
简易版抽奖活动的设计技术方案
1.前言 本技术方案旨在设计一套完整且可靠的抽奖活动逻辑,确保抽奖活动能够公平、公正、公开地进行,同时满足高并发访问、数据安全存储与高效处理等需求,为用户提供流畅的抽奖体验,助力业务顺利开展。本方案将涵盖抽奖活动的整体架构设计、核心流程逻辑、关键功能实现以及…...
《Playwright:微软的自动化测试工具详解》
Playwright 简介:声明内容来自网络,将内容拼接整理出来的文档 Playwright 是微软开发的自动化测试工具,支持 Chrome、Firefox、Safari 等主流浏览器,提供多语言 API(Python、JavaScript、Java、.NET)。它的特点包括&a…...
大语言模型如何处理长文本?常用文本分割技术详解
为什么需要文本分割? 引言:为什么需要文本分割?一、基础文本分割方法1. 按段落分割(Paragraph Splitting)2. 按句子分割(Sentence Splitting)二、高级文本分割策略3. 重叠分割(Sliding Window)4. 递归分割(Recursive Splitting)三、生产级工具推荐5. 使用LangChain的…...
ffmpeg(四):滤镜命令
FFmpeg 的滤镜命令是用于音视频处理中的强大工具,可以完成剪裁、缩放、加水印、调色、合成、旋转、模糊、叠加字幕等复杂的操作。其核心语法格式一般如下: ffmpeg -i input.mp4 -vf "滤镜参数" output.mp4或者带音频滤镜: ffmpeg…...
MySQL 8.0 OCP 英文题库解析(十三)
Oracle 为庆祝 MySQL 30 周年,截止到 2025.07.31 之前。所有人均可以免费考取原价245美元的MySQL OCP 认证。 从今天开始,将英文题库免费公布出来,并进行解析,帮助大家在一个月之内轻松通过OCP认证。 本期公布试题111~120 试题1…...
基于matlab策略迭代和值迭代法的动态规划
经典的基于策略迭代和值迭代法的动态规划matlab代码,实现机器人的最优运输 Dynamic-Programming-master/Environment.pdf , 104724 Dynamic-Programming-master/README.md , 506 Dynamic-Programming-master/generalizedPolicyIteration.m , 1970 Dynamic-Programm…...
代理篇12|深入理解 Vite中的Proxy接口代理配置
在前端开发中,常常会遇到 跨域请求接口 的情况。为了解决这个问题,Vite 和 Webpack 都提供了 proxy 代理功能,用于将本地开发请求转发到后端服务器。 什么是代理(proxy)? 代理是在开发过程中,前端项目通过开发服务器,将指定的请求“转发”到真实的后端服务器,从而绕…...
R语言速释制剂QBD解决方案之三
本文是《Quality by Design for ANDAs: An Example for Immediate-Release Dosage Forms》第一个处方的R语言解决方案。 第一个处方研究评估原料药粒径分布、MCC/Lactose比例、崩解剂用量对制剂CQAs的影响。 第二处方研究用于理解颗粒外加硬脂酸镁和滑石粉对片剂质量和可生产…...
springboot整合VUE之在线教育管理系统简介
可以学习到的技能 学会常用技术栈的使用 独立开发项目 学会前端的开发流程 学会后端的开发流程 学会数据库的设计 学会前后端接口调用方式 学会多模块之间的关联 学会数据的处理 适用人群 在校学生,小白用户,想学习知识的 有点基础,想要通过项…...
