线程池的使用——线程池的创建方式
线程池的使用——创建线程
- 线程池的创建
- 线程池的创建方式
- Executors.newFixedThreadPool:
- Executors.newCachedThreadPool:
- Executors.newSingleThreadExecutor:
- Executors.newScheduledThreadPool:
- Executors.newSingleThreadScheduledExecutor:
- Executors.newWorkStealingPool:
- ThreadPoolExecutor:
- 线程池的拒绝策略
- ThreadPoolExecutor.AbortPolicy:
- ThreadPoolExecutor.DiscardPolicy:
- ThreadPoolExecutor.DiscardOldestPolicy:
- ThreadPoolExecutor.CallerRunsPolicy:
线程池的创建
线程池的创建方法总共有 7 种,但总体来说可分为 2 类:
- 一类是通过 ThreadPoolExecutor 创建的线程池;
- 另一个类是通过 Executors 创建的线程池。
线程池的创建方式
Executors.newFixedThreadPool:
创建一个固定大小的线程池,可控制并发的线程数,超出的线程会在队列中等待
;
// 创建一个固定大小的线程池,可控制并发的线程数,超出的线程会在队列中等待ExecutorService executorService = Executors.newFixedThreadPool(3);// 创建任务Runnable runnable = new Runnable() {@Overridepublic void run() {System.out.println("任务被执行,线程:" + Thread.currentThread().getName());}};executorService.submit(runnable); // 执行方式 1:submitexecutorService.execute(runnable); // 执行方式 2:executeexecutorService.execute(runnable);executorService.execute(runnable);//结束线程池executorService.shutdown();
执行结果如下:
超出线程数量的任务会在队列中等待,其他任务执行完毕之后再获取线程执行任务。
任务被执行,线程:pool-1-thread-1
任务被执行,线程:pool-1-thread-3
任务被执行,线程:pool-1-thread-2
任务被执行,线程:pool-1-thread-3
Executors.newCachedThreadPool:
创建一个可缓存的线程池,若线程数超过处理所需,缓存一段时间后会回收,若线程数不够,则新建线程;
ExecutorService executorService = Executors.newCachedThreadPool(Executors.defaultThreadFactory());// 创建任务Runnable runnable = new Runnable() {@Overridepublic void run() {System.out.println("任务被执行,线程:" + Thread.currentThread().getName());}};// 线程池执行任务(一次添加 4 个任务)// 执行任务的方法有两种:submit 和 executefor (int i = 0; i < 10 ; i++) {executorService.submit(runnable); // 执行方式 1:submitexecutorService.execute(runnable); // 执行方式 2:executeexecutorService.execute(runnable);executorService.execute(runnable);}executorService.shutdown();
运行结果如下:
任务被执行,线程:pool-1-thread-1
任务被执行,线程:pool-1-thread-1
任务被执行,线程:pool-1-thread-3
任务被执行,线程:pool-1-thread-4
任务被执行,线程:pool-1-thread-2
任务被执行,线程:pool-1-thread-5
任务被执行,线程:pool-1-thread-6
任务被执行,线程:pool-1-thread-7
任务被执行,线程:pool-1-thread-9
任务被执行,线程:pool-1-thread-10
任务被执行,线程:pool-1-thread-14
任务被执行,线程:pool-1-thread-13
任务被执行,线程:pool-1-thread-15
任务被执行,线程:pool-1-thread-16
任务被执行,线程:pool-1-thread-18
任务被执行,线程:pool-1-thread-20
任务被执行,线程:pool-1-thread-17
任务被执行,线程:pool-1-thread-22
任务被执行,线程:pool-1-thread-23
任务被执行,线程:pool-1-thread-25
任务被执行,线程:pool-1-thread-27
任务被执行,线程:pool-1-thread-28
任务被执行,线程:pool-1-thread-30
任务被执行,线程:pool-1-thread-29
任务被执行,线程:pool-1-thread-32
任务被执行,线程:pool-1-thread-31
任务被执行,线程:pool-1-thread-33
任务被执行,线程:pool-1-thread-35
任务被执行,线程:pool-1-thread-39
任务被执行,线程:pool-1-thread-36
任务被执行,线程:pool-1-thread-8
任务被执行,线程:pool-1-thread-19
任务被执行,线程:pool-1-thread-21
任务被执行,线程:pool-1-thread-24
任务被执行,线程:pool-1-thread-34
任务被执行,线程:pool-1-thread-38
任务被执行,线程:pool-1-thread-11
任务被执行,线程:pool-1-thread-12
任务被执行,线程:pool-1-thread-26
任务被执行,线程:pool-1-thread-37
Executors.newSingleThreadExecutor:
创建单个线程数的线程池,它可以保证先进先出的执行顺序;
ExecutorService executorService = Executors.newSingleThreadExecutor(Executors.defaultThreadFactory());// 创建任务Runnable runnable = new Runnable() {@Overridepublic void run() {System.out.println("任务被执行,线程:" + Thread.currentThread().getName());}};// 线程池执行任务(一次添加 4 个任务)// 执行任务的方法有两种:submit 和 executefor (int i = 0; i < 10 ; i++) {executorService.submit(runnable); // 执行方式 1:submitexecutorService.execute(runnable); // 执行方式 2:executeexecutorService.execute(runnable);executorService.execute(runnable);}executorService.shutdown();
执行结果如下
任务被执行,线程:pool-1-thread-1
任务被执行,线程:pool-1-thread-1
任务被执行,线程:pool-1-thread-1
任务被执行,线程:pool-1-thread-1
任务被执行,线程:pool-1-thread-1
任务被执行,线程:pool-1-thread-1
...
Executors.newScheduledThreadPool:
创建一个可以执行延迟任务的线程池;
ScheduledExecutorService scheduledExecutorService = Executors.newScheduledThreadPool(3);System.out.println("任务添加时间"+ new Date());ScheduledFuture<Date> schedul = scheduledExecutorService.schedule(()->{return new Date();}, 3, TimeUnit.SECONDS);System.out.println("任务执行完毕" + schedul.get());
运行结果如下:
在2秒钟后执行一次任务,线程阻塞等待结果返回。执行完成并返回结果后就结束。
任务添加时间Thu Mar 02 20:50:12 CST 2023
任务执行完毕Thu Mar 02 20:50:15 CST 2023
Executors.newSingleThreadScheduledExecutor:
创建一个单线程的可以执行延迟任务的线程池;
public static void SingleThreadScheduledExecutor() {// 创建线程池ScheduledExecutorService threadPool = Executors.newSingleThreadScheduledExecutor();// 添加定时执行任务(2s 后执行)System.out.println("添加任务,时间:" + new Date());threadPool.schedule(() -> {System.out.println("任务被执行,时间:" + new Date());try {TimeUnit.SECONDS.sleep(1);} catch (InterruptedException e) {}}, 2, TimeUnit.SECONDS);
}
执行结果如下:

Executors.newWorkStealingPool:
创建一个抢占式执行的线程池(任务执行顺序不确定)【JDK 1.8 添加】。
public static void workStealingPool() {// 创建线程池ExecutorService threadPool = Executors.newWorkStealingPool();// 执行任务for (int i = 0; i < 10; i++) {final int index = i;threadPool.execute(() -> {System.out.println(index + " 被执行,线程名:" + Thread.currentThread().getName());});}// 确保任务执行完成while (!threadPool.isTerminated()) {}
}
运行结果如下:
从上述结果可以看出,任务的执行顺序是不确定的,因为它是抢占式执行的。

ThreadPoolExecutor:
最原始的创建线程池的方式,它包含了 7 个参数可供设置。
public static void myThreadPoolExecutor() {// 创建线程池ThreadPoolExecutor threadPool = new ThreadPoolExecutor(5, 10, 100, TimeUnit.SECONDS, new LinkedBlockingQueue<>(10));// 执行任务for (int i = 0; i < 10; i++) {final int index = i;threadPool.execute(() -> {System.out.println(index + " 被执行,线程名:" + Thread.currentThread().getName());try {Thread.sleep(1000);} catch (InterruptedException e) {e.printStackTrace();}});}
}
执行结果如下:

线程池的拒绝策略
当线程池的任务缓存队列已满并且线程池中的线程数目达到maximumPoolSize时,如果还有任务到来就会采取任务拒绝策略,通常有以下四种策略:
ThreadPoolExecutor.AbortPolicy:
丢弃任务并抛出RejectedExecutionException异常。
ThreadPoolExecutor.DiscardPolicy:
丢弃任务,但是不抛出异常。
ThreadPoolExecutor.DiscardOldestPolicy:
丢弃队列最前面的任务,然后重新提交被拒绝的任务
ThreadPoolExecutor.CallerRunsPolicy:
由调用线程(提交任务的线程)处理该任务
相关文章:
线程池的使用——线程池的创建方式
线程池的使用——创建线程线程池的创建线程池的创建方式Executors.newFixedThreadPool:Executors.newCachedThreadPool:Executors.newSingleThreadExecutor:Executors.newScheduledThreadPool:Executors.newSingleThreadScheduled…...
代码随想录算法训练营day47 |动态规划 198打家劫舍 213打家劫舍II 337打家劫舍III
day47198.打家劫舍1.确定dp数组(dp table)以及下标的含义2.确定递推公式3.dp数组如何初始化4.确定遍历顺序5.举例推导dp数组213.打家劫舍II情况一:考虑不包含首尾元素情况二:考虑包含首元素,不包含尾元素情况三&#x…...
项目设计模式和规范
1、责任链模式 自己的理解:避免发生方与接收方解耦 优点:①降低发送方与接收方的耦合 ②简化他们对象 ③方便扩展新增 处理者 缺点:①不方便排错 ②性能问题,且使用不当容易搞出死循环 应用场景:拦截器 Interceptor和过滤器 filter:符合模式的进行拦截或者过滤到,然…...
无线WiFi安全渗透与攻防(一)之无线安全环境搭建
无线安全环境搭建 1.802.11标准 (1).概念 802.11标准是1997年IEEE最初制定的一个WLAN标准,工作在2.4GHz开放频段,支持1Mbit/s和2Mbit/s的数据传输速率,定义了物理层和MAC层规范,允许无线局域网及无线设备…...
【matplotlib】可视化解决方案——如何解决matplotlib中文乱码问题
问题概述 Matplotlib 默认不支持中文字体,这是因为 matplotlib 只支持 ASCII 字符,但是国人使用 matplotlib 肯定需要中文标注。如下图所示,当不对 Matplotlib 进行设置,而直接使用中文时,绘制的图像会出现中文乱码。…...
JAVA开发中GC日志打印简单通用的配置详解
如何配置一个完美的JVM日志打印信息 打印内容 打印基本的GC信息 打印对象分布情况 GC后打印堆数据 打印STW时间 打印safepoint信息 打印Reference处理信息 综上所述,最终的参数如下: 还有哪些问题呢?是不是有文件输出更好? 打印日…...
十进制的小数如何转二进制?二进制表示的小数如何转十进制?
😄 基础不牢,地动山摇~ 补补基础~ 文章目录 1、十进制的小数转二进制?2、二进制表示的小数转十进制?3、做道coding题巩固下:1、十进制的小数转二进制? 整数部分: 用普通的二进制表示即可。小数部分: 首先,将小数部分乘以2,取出整数部分作为二进制表示的第1位;然后…...
klipper使用webcam设置多个摄像头方式
一、前言 使用klipper设置多个摄像头,折腾了好些天,网上资料很少,这里写一个帖子记录一下 二、环境 参考链接:https://www.cnblogs.com/sjqlwy/p/klipper_webcam.html 我的klipper安装在香橙派上面,系统是debian&a…...
风力发电机组浪涌保护器安全防护方案
风机的庞大与危险高空作业注定了其在基建和维护中不易操作,风机设备的主电源、过程控制、网络与通讯、现场设备需要高等级的防雷浪涌保护器冲击保护,提高系统及设备的可靠性和可用性。风电场的主要发电设备风力发电机组“大风车”是风电场的主要发电设备…...
【剑指offer】JZ7 重建二叉树、JZ9 用两个栈实现队列
\描述: 给定节点数为 n 的二叉树的前序遍历和中序遍历结果,请重建出该二叉树并返回它的头结点。 例如输入前序遍历序列{1,2,4,7,3,5,6,8}和中序遍历序列{4,7,2,1,5,3,8,6},则重建出如下图所示。 思路: 题上给了我们前序遍历(根 …...
ElasticSearch - SpringBoot整合ES之查询所有 match_all
文章目录1. 数据准备2. 全量查询 match_all3. 使用 boost 参数更改 _score官方文档地址:https://www.elastic.co/guide/en/elasticsearch/reference/index.html权威指南:https://www.elastic.co/guide/cn/elasticsearch/guide/current/structured-search…...
详谈IIC
前言 在嵌入式底层系统中,常见的通讯方式,串口,IIC,SPI,IIS等,一般IIC,SPI,IIS更多的采取IO模拟,其余CAN,UART均是硬件设计直接支持,而IIC主要用于多数传感器数据的读写,…...
【Autoware】采集实验数据bag包并仿真运行
文章目录1. 官方demo包2. 控制底层地图采集3. 感知定位4. 规划控制5. 仿真或实车运行1. 官方demo包 wget http://db3.ertl.jp/autoware/sample_data/sample_moriyama_data.tar.gz wget http://db3.ertl.jp/autoware/sample_data/sample_moriyama_150324.tar.gz官方示例包的网上…...
名创优品怎么把创意做成生意?
最近,“主”无处不在,从让“依托答辩”梗火出圈的动画《三体》,到备受好评的电视剧《三体》,再到仍在刷新高票房成绩的《流浪地球2》。作为近些年来中国为数不多的爆款IP制造者,刘慈欣在《三体》中提出了一个著名的理论…...
springboot原项目配置文件迁移至nacos
目录一、配置文件迁移nacos1.安装nacos2.添加依赖3.改造service-product3.改造server-gateway一、配置文件迁移nacos 1.安装nacos 1,如果之前安装过nacos,nacos数据保存至mysql,先删除已安装的nacos,再安装 docker stop nacos …...
常用的shell脚步操作
文章目录一、如何开始一个shell脚本?1.基本语法2.变量定义规则二、特色变量1.$n2.$?三、条件判断1.基本语法2.运算符if,for,while四、字符串切割1.从指定位置开始截取从字符串左边开始计数从右边开始计数2.从指定字符(子字符串)开…...
Java on VS Code 2月更新|JUnit 5 并行测试与 Spring Boot 插件的过滤功能
作者:Nick Zhu - Senior Program Manager, Developer Division at Microsoft 排版:Alan Wang 大家好,欢迎来到我们的二月更新!在此博客中,我们将为您带来与 JUnit 5 并行测试相关的新功能以及用于 Spring Boot Dashboa…...
无线WiFi安全渗透与攻防(三)之Windows扫描wifi和破解WiFi密码
系列文章 无线WiFi安全渗透与攻防(一)之无线安全环境搭建 无线WiFi安全渗透与攻防(二)之打造专属字典 windows下wifi进行扫描和破解 1.wifi扫描 (1).软件介绍 WirelessMon是一款无线网络扫描工具,它可以帮助用户扫描附近的无线信号&…...
Python中的遍历字典的键和值
一、Python的字典在项目的开发过程中,如果遇到有映射关系的内容可以考虑使用Python中的字典进行存储数据,字典中冒号前的数据称为【键】、冒号后的数据称为【值】。二、Python字典的用法2.1、Python的定义#Python字典的定义 字典名称{键1:值1,键2:值2,键…...
三天Golang快速入门—结构体
Struct结构体什么是结构体结构体定义基本实例化new实例化键值对初始化结构体方法和接收者结构体说明结构体方法和接收者值类型和指针类型接收者struct与jsonstruct转json字符串json转structstruct tagTag结构体转化Json字符串Json字符串转成Tag结构体什么是结构体 1.Golang中没…...
【Linux】C语言执行shell指令
在C语言中执行Shell指令 在C语言中,有几种方法可以执行Shell指令: 1. 使用system()函数 这是最简单的方法,包含在stdlib.h头文件中: #include <stdlib.h>int main() {system("ls -l"); // 执行ls -l命令retu…...
论文浅尝 | 基于判别指令微调生成式大语言模型的知识图谱补全方法(ISWC2024)
笔记整理:刘治强,浙江大学硕士生,研究方向为知识图谱表示学习,大语言模型 论文链接:http://arxiv.org/abs/2407.16127 发表会议:ISWC 2024 1. 动机 传统的知识图谱补全(KGC)模型通过…...
ardupilot 开发环境eclipse 中import 缺少C++
目录 文章目录 目录摘要1.修复过程摘要 本节主要解决ardupilot 开发环境eclipse 中import 缺少C++,无法导入ardupilot代码,会引起查看不方便的问题。如下图所示 1.修复过程 0.安装ubuntu 软件中自带的eclipse 1.打开eclipse—Help—install new software 2.在 Work with中…...
MySQL 8.0 OCP 英文题库解析(十三)
Oracle 为庆祝 MySQL 30 周年,截止到 2025.07.31 之前。所有人均可以免费考取原价245美元的MySQL OCP 认证。 从今天开始,将英文题库免费公布出来,并进行解析,帮助大家在一个月之内轻松通过OCP认证。 本期公布试题111~120 试题1…...
Kafka入门-生产者
生产者 生产者发送流程: 延迟时间为0ms时,也就意味着每当有数据就会直接发送 异步发送API 异步发送和同步发送的不同在于:异步发送不需要等待结果,同步发送必须等待结果才能进行下一步发送。 普通异步发送 首先导入所需的k…...
DingDing机器人群消息推送
文章目录 1 新建机器人2 API文档说明3 代码编写 1 新建机器人 点击群设置 下滑到群管理的机器人,点击进入 添加机器人 选择自定义Webhook服务 点击添加 设置安全设置,详见说明文档 成功后,记录Webhook 2 API文档说明 点击设置说明 查看自…...
关于uniapp展示PDF的解决方案
在 UniApp 的 H5 环境中使用 pdf-vue3 组件可以实现完整的 PDF 预览功能。以下是详细实现步骤和注意事项: 一、安装依赖 安装 pdf-vue3 和 PDF.js 核心库: npm install pdf-vue3 pdfjs-dist二、基本使用示例 <template><view class"con…...
Kubernetes 节点自动伸缩(Cluster Autoscaler)原理与实践
在 Kubernetes 集群中,如何在保障应用高可用的同时有效地管理资源,一直是运维人员和开发者关注的重点。随着微服务架构的普及,集群内各个服务的负载波动日趋明显,传统的手动扩缩容方式已无法满足实时性和弹性需求。 Cluster Auto…...
Java详解LeetCode 热题 100(26):LeetCode 142. 环形链表 II(Linked List Cycle II)详解
文章目录 1. 题目描述1.1 链表节点定义 2. 理解题目2.1 问题可视化2.2 核心挑战 3. 解法一:HashSet 标记访问法3.1 算法思路3.2 Java代码实现3.3 详细执行过程演示3.4 执行结果示例3.5 复杂度分析3.6 优缺点分析 4. 解法二:Floyd 快慢指针法(…...
Mysql故障排插与环境优化
前置知识点 最上层是一些客户端和连接服务,包含本 sock 通信和大多数jiyukehuduan/服务端工具实现的TCP/IP通信。主要完成一些简介处理、授权认证、及相关的安全方案等。在该层上引入了线程池的概念,为通过安全认证接入的客户端提供线程。同样在该层上可…...
