【JavaEE】多线程(7) -- 线程池的概念和简单实现

目录
1.线程池是什么
2.标准库中的线程池
2.1ThreadPoolExecutor
2.2构造方法参数介绍
2.3拒绝策略(面试易考)
2.4Executor的使用
3.实现线程池
1.线程池是什么
线程池是一种用来管理线程的机制,它可以有效地控制线程的创建、复用和销毁,从而提高程序的性能和资源利用率。
想象这么⼀个场景:
在学校附近新开了⼀家快递店,老板很精明,想到⼀个与众不同的办法来经营。店里没有雇⼈,而是 每次有业务来了,就现场找⼀名同学过来把快递送了,然后解雇同学。这个类⽐我们平时来⼀个任 务,起⼀个线程进行处理的模式。
很快⽼板发现问题来了,每次招聘 + 解雇同学的成本还是非常高的。老板还是很善于变通的,知道 了为什么⼤家都要雇⼈了,所以指定了⼀个指标,公司业务⼈员会扩张到 3 个⼈,但还是随着业务 逐步雇⼈。于是再有业务来了,老板就看,如果现在公司还没 3 个⼈,就雇⼀个⼈去送快递,否则 只是把业务放到⼀个本本上,等着 3 个快递⼈员空闲的时候去处理。这个就是我们要带出的线程池的模式。
线程池最大的好处就是减少每次启动、销毁线程的损耗。
2.标准库中的线程池
2.1ThreadPoolExecutor
2.2构造方法参数介绍
以最后一个构造方法为例:

Java的 ThreadPoolExecutor 是一个线程池执行器,用于管理和调度线程的执行。它有以下几个参数:
1.corePoolSize:核心线程数
即线程池中保持活动状态的最小线程数。如果线程池中的线程数小于corePoolSize,则即使其他线程是空闲的,ThreadPoolExecutor也会创建新的线程来处理任务。
2.maximumPoolSize:最大线程数
即线程池中允许的最大线程数。当队列满了且当前线程数小于maximumPoolSize时,ThreadPoolExecutor会创建新的线程来处理任务。
3.keepAliveTime:线程保持活动的时间
即当线程池中的线程数量大于corePoolSize时,空闲线程被保留的最长时间。超过这个时间,空闲线程将被终止。
4.unit:线程保持活动时间的单位
可以是纳秒、微秒、毫秒、秒、分钟、小时或天。
5.workQueue:任务队列
用于保存等待执行的任务。ThreadPoolExecutor提供了多种类型的队列,如ArrayBlockingQueue、LinkedBlockingQueue、SynchronousQueue等。
6.threadFactory:线程工厂
用于创建新线程。可以通过实现ThreadFactory接口来自定义线程的创建过程。
7.handler:拒绝策略
用于处理无法添加到线程池的任务。拒绝策略可以ThreadPoolExecutor提供的几种默认策略,如AbortPolicy、CallerRunsPolicy、DiscardPolicy和DiscardOldestPolicy,也可以自定义实现RejectedExecutionHandler接口来定义自己的策略。
这些参数可以通过ThreadPoolExecutor的构造方法来设置,也可以通过相应的setter方法进行设置。根据具体的需求,可以调整这些参数来优化线程池的性能和行为。
2.3拒绝策略(面试易考)
在多线程编程中,当线程池无法接受新的任务时,就会触发拒绝策略(RejectedExecutionHandler)。拒绝策略是一个接口,用于定义当线程池无法接受新的任务时应该如何处理这些被拒绝的任务。
在Java中,有四种内置的拒绝策略:
1.AbortPolicy(默认):当线程池无法接受新的任务时,会抛出RejectedExecutionException异常。
2.CallerRunsPolicy:当线程池无法接受新的任务时,会由调用execute方法的线程来执行该任务。
3.DiscardOldestPolicy:当线程池无法接受新的任务时,会抛弃队列中最旧的任务,然后尝试再次提交新的任务。
4.DiscardPolicy:当线程池无法接受新的任务时,会直接抛弃被拒绝的任务。
除了以上四种内置的拒绝策略,我们还可以自定义拒绝策略,只需要实现RejectedExecutionHandler接口,并实现其唯一的方法rejectedExecution(Runnable r, ThreadPoolExecutor executor)。在该方法中,可以根据需求实现自定义的拒绝逻辑,如记录日志、发送通知等。然后,可以通过ThreadPoolExecutor的setRejectedExecutionHandler方法将自定义的拒绝策略设置给线程池。
ThreadPoolExecutor 本身用起来比较复杂, 因此标准库还提供了另一个版本, 把ThreadPoolExecutor封装了一下. 这个版本就是Executors类.
Executors类创建的线程池适用于一些简单的场景,不需要过多的自定义配置。而ThreadPoolExecutor适用于需要更多自定义配置的场景,可以根据需要灵活地配置线程池。
Executors中的方法:

2.4Executor的使用
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;public class ThreadDemo32 {public static void main(String[] args) {ExecutorService service = Executors.newFixedThreadPool(4);//使用submit添加任务service.submit(new Runnable() {@Overridepublic void run() {System.out.println("hello");}});//ThreadPoolExecutor也是通过submit添加任务, 只是构造方法不同}
}
3.实现线程池
- 核⼼操作为 submit, 将任务加⼊线程池中
- 使⽤ Worker 类描述⼀个⼯作线程. 使⽤ Runnable 描述⼀个任务.
- 使⽤⼀个 BlockingQueue 组织所有的任务
- 每个 worker 线程要做的事情: 不停的从 BlockingQueue 中取任务并执⾏.
- 指定⼀下线程池中的最⼤线程数 maxWorkerCount; 当当前线程数超过这个最⼤值时, 就不再新增 线程了.
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.ArrayBlockingQueue;
import java.util.concurrent.BlockingQueue;class MyThreadPoolExecutor {private final List<Thread> threadList = new ArrayList<>();private BlockingQueue<Runnable> queue = new ArrayBlockingQueue<>(1000);//n来指定创多少的线程public MyThreadPoolExecutor(int 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) {e.printStackTrace();}}});t.start();threadList.add(t);}}public void submit(Runnable runnable) throws InterruptedException {queue.put(runnable);}
}
使用示例:
public class ThreadDemo33 {public static void main(String[] args) throws InterruptedException {MyThreadPoolExecutor executor = new MyThreadPoolExecutor(4);for (int i = 0; i < 1000; i++) {int n = i;executor.submit(new Runnable() {@Overridepublic void run() {System.out.println("执行任务" + n + ", 当前线程为:" + Thread.currentThread().getName());}});}}
}


相关文章:
【JavaEE】多线程(7) -- 线程池的概念和简单实现
目录 1.线程池是什么 2.标准库中的线程池 2.1ThreadPoolExecutor 2.2构造方法参数介绍 2.3拒绝策略(面试易考) 2.4Executor的使用 3.实现线程池 1.线程池是什么 线程池是一种用来管理线程的机制,它可以有效地控制线程的创建、复用和销毁,从而提高程…...
集合基础知识点
集合基础 1. 集合的由来 当 Java 程序中需要存放数据的时候,通常会定义变量来实现数据的存储,但是,当需要存储大量数据的时候该怎么办呢?这时首先想到的是数组,但是!数组只能存放同一类型的数据ÿ…...
最新版付费进群系统源码 /同城定位付费进群源码 /自带定位完整版/后台分销站点
源码介绍: 最新版付费进群系统源码 ,它是同城定位付费进群源码,而且自带定位完整版和后台分销站点。 看到有些人分享一些虚假的内容或者缺少文件的内容。现在分享完整给大家,功能是完整的。它是同城定位付费进群源码。 功能&am…...
【论文阅读笔记】医学多模态新数据集-Large-scale Long-tailed Disease Diagnosis on Radiology Images
这是复旦大学2023.12.28开放出来的数据集和论文,感觉很宝藏,稍微将阅读过程记录一下。 Zheng Q, Zhao W, Wu C, et al. Large-scale Long-tailed Disease Diagnosis on Radiology Images[J]. arXiv preprint arXiv:2312.16151, 2023. 项目主页…...
(C语言)指针的进阶
1.指针就是个变量,用来存放地址,地址唯一标识一块内存空间。 2.指针的大小是固定的4/8个字节(32位平台/64位平台)。 3.指针是有类型,指针的类型决定了指针的-整数的步长,指针解引用操作的时候的权限。 4.指针的运算。 一、关于两…...
【网络面试(5)】收发数据及断开服务器(四次挥手)
前面了解到服务器和客户端在创建套接字,建立连接后,就可以进入到下一步,双发可以互相发送和接收数据,本篇博客就来学习一下这个过程。 我们印象里,发送数据应该是我们在浏览器输入网址,敲击回车的一瞬间&…...
【Maven】下载及配置
文章目录 1. 定义2. 下载3. 解压4. 配置环境变量5. 验证6. 特性 1. 定义 Maven 是一个跨平台的项目管理工具。作为 Apache 组织的一个颇为成功的开源项目,其主要服务于基于 Java 平台的项目创建,依赖管理和项目信息管理,是一个自动化构建工具…...
【方法】PPT设置密码后如何修改?
PowerPoint是我们日常和工作中经常用到的办公软件,有时候为了保护文件,还会设置密码,那设置密码后又想要修改密码,怎么操作呢?下面来看看PPT常用的两种密码是如何修改的。 1. “打开密码” 想要修改PPT的“打开密码”…...
第34期 | GPTSecurity周报
GPTSecurity是一个涵盖了前沿学术研究和实践经验分享的社区,集成了生成预训练Transformer(GPT)、人工智能生成内容(AIGC)以及大型语言模型(LLM)等安全领域应用的知识。在这里,您可以…...
2023新版edge浏览器页面加载不出来的解决办法
2023新版edge浏览器页面加载不出来的原因有很多,以下是一些可能的解决方法: - 检查网络连接:确保你的设备连接到稳定的网络,尝试重新启动路由器或调制解调器。 - 清除浏览器缓存:打开edge浏览器,点击右上…...
算法基础之二分与前缀和 day 6
文章目录 二分第一类第二类 前缀和原题链接题目描述输入格式输出格式数据范围输入样例:输出样例: 题目分析示例代码 二分 二分法是我们在高中数学就学习过的一种思想,他也是一种效率较高的查找算法,在编写代码的过程中࿰…...
github短视频去除水印项目Douyin_TikTok_Download_API介绍
当下正值短视频盛行的时代。在我们浏览短视频的同时,经常能发现一些精美的图片、引人入胜的文案以及吸引眼球的视频,想要将它们保存到本地。然而,保存下来的图片或视频通常伴随着不太愉悦的水印,这显著降低了使用体验。因此&#…...
FindMy技术用于键盘
键盘是我们生活中不可或缺的输入工具,是人与计算机之间沟通的桥梁,无论是编写文档、浏览网页、玩游戏、或是进行复杂的数据分析,键盘都在其中发挥着关键的作用。此外,键盘还是各种软件的快捷键操作的关键。通过熟练地运用快捷键&a…...
认识jmeter接口测试工具!
jmeter简介 Apache JMeter是Apache组织开发的基于Java的压力测试工具。用于对软件做压力测试,它最初被设计用于Web应用测试,但后来扩展到其他测试领域。 下载 下载地址:Apache JMeter - Download Apache JMeter 安装 由于Jmeter…...
强大的按钮类CButtonST
转自:哈哈 强大的CButtonST_cbuttonst demo-CSDN博客 这里给大家介绍强大的按钮类CButtonST,可以使您的程序锦上添花。 CButtonST类主要包括BtnST.h、BtnST.cpp、BCMenu.h和BCMenu.cpp四个文件。先将上述4个文件复制到自己的工程,然后在VC开…...
学习ing
记录 1.光圈的大小由一个称为“F值”的数字表示,这个数字越小,光圈就越大,光线也就越多。一般来说,使用较小的F值可以拍摄出更亮的照片,而使用较大的F值可以拍摄出更暗的照片。 2.光圈可以控制相机的曝光时间&#x…...
linux下数据库定时备份
1.编写shell脚本 #!/bin/bash USER"root" PASSWORD"Root.36#336" DATABASE"backup_test" HOSTNAME"127.0.0.1" DATEdate %Y%m%d_%H%M%S #日期格式(作为文件名) BACKUP_DIR/home/mysql/DB_backup/ #备份文件存…...
Qt/QML编程学习之心得:QSocketNotifier(二十一)
QSocketNotifier在Qt中怎么使用? QSocketNotifier使Qt的事件循环与其他基于文件描述符的事件循环集成成为可能。在Qt的主事件循环(QCoreApplication::exec())中检测到文件描述符操作。 使用低级(通常是特定于平台的)API打开设备后,可以创建一个套接字通知程序来监视文…...
【linux】lsblk和df -h显示的磁盘信息不同
【问题分析】 lsblk 查看的是block device,也就是逻辑磁盘大小。 df查看的是file system, 也就是文件系统层的磁盘大小。 这种情况应该是block device容量变大,单还没有反映到file system中。 【问题解决】 如果是ext{2,3,4}文件系统的话,可以用res…...
如何开发属于自己的小程序?
随着移动互联网的快速发展,小程序已成为一种不可忽视的力量。对于许多企业和个人而言,拥有一个属于自己的小程序不仅能提高品牌曝光度,还能带来实实在在的收益。那么,如何开发属于自己的小程序呢?本文将为你揭秘这一过…...
告别“AI失忆“!掌握Harness Engineering,让AI秒变高效生产力工具
文章指出AI难以胜任长周期复杂任务并非因"不够聪明",而是缺乏工程化工作方式。核心解法是引入Harness运行框架,通过外部记忆替代上下文依赖、强制任务拆解、建立固定执行循环及测试优先机制,将AI从单打独斗的"代码生成器"…...
Notepad++插件安装失败?手把手教你搞定NppFTP(含离线安装包和兼容性解决方案)
Notepad插件安装失败?手把手教你搞定NppFTP(含离线安装包和兼容性解决方案) 作为开发者日常必备的文本编辑器,Notepad凭借轻量高效的特点广受欢迎。而NppFTP插件更是让这款编辑器如虎添翼,实现了直接通过FTP/SFTP协议远…...
避坑指南:在FPGA上实现DP SST协议时,最容易搞错的BS/SR时序与填充规则
FPGA实战避坑:DP SST协议中BS/SR时序与填充规则的7个致命误区 DisplayPort单流传输(SST)协议在FPGA实现过程中,那些看似简单的BS(Blanking Start)和SR(Scrambler Reset)时序规则,往往成为视频流异常的罪魁祸首。去年在为某8K视频采集卡调试DP…...
造相-Z-Image实战手册:基于Z-Image的AIGC版权合规提示词生成规范
造相-Z-Image实战手册:基于Z-Image的AIGC版权合规提示词生成规范 1. 项目概述与核心价值 造相-Z-Image是一款专为RTX 4090显卡优化的本地化文生图系统,基于通义千问官方Z-Image模型构建。这个项目最大的特点是将强大的AI图像生成能力带到了个人电脑上&…...
PCA9685嵌入式C++驱动库:高效I²C PWM控制方案
1. PCA9685 LED驱动库技术解析:面向嵌入式C的高效IC PWM控制方案1.1 芯片级原理与工程定位PCA9685是NXP(原Philips)推出的16通道12位PWM LED驱动器,采用标准IC(TWI)接口通信,支持最高1.6 MHz时钟…...
视频硬字幕提取终极指南:本地化AI工具让字幕制作效率提升10倍
视频硬字幕提取终极指南:本地化AI工具让字幕制作效率提升10倍 【免费下载链接】video-subtitle-extractor 视频硬字幕提取,生成srt文件。无需申请第三方API,本地实现文本识别。基于深度学习的视频字幕提取框架,包含字幕区域检测、…...
手写 Vue3 自定义指令:防抖、点击外部、权限控制
在 Vue3 开发中,指令(Directive)是一个非常实用的特性,它允许我们在 DOM 元素上添加自定义行为,封装可复用的逻辑。Vue3 内置了 v-model、v-show、v-bind 等常用指令,但在实际开发中,我们经常会…...
百川2-13B-4bits模型调优:OpenClaw任务响应速度提升50%的3个技巧
百川2-13B-4bits模型调优:OpenClaw任务响应速度提升50%的3个技巧 1. 问题背景与优化动机 去年冬天,当我第一次将百川2-13B-4bits模型接入OpenClaw时,发现一个奇怪现象:同样的自动化任务,在本地测试时响应飞快&#x…...
Vivo Xplay6专用降级刷机工具AFTool|支持1.15.1/1.16.6/1.16.14等多版本线刷|含教程+驱动+工具包
温馨提示:文末有联系方式【适用机型精准说明】 本工具包专为Vivo Xplay6(型号V317A/V317K)深度适配,非Xplay6机型(含其他Vivo手机)请勿购买——不同机型Bootloader锁机制与分区结构差异极大,强行…...
开源吐槽大会:技术人的快乐与烦恼
开源项目吐槽大会:技术文章大纲技术吐槽的核心议题开源项目的常见痛点:文档不全、代码混乱、维护停滞 社区互动的典型问题:响应慢、沟通低效、贡献者流失 技术债务与设计缺陷:历史包袱、架构不合理、兼容性差吐槽背后的技术分析代…...

