【JAVAEE】线程池基础知识⭐
目录
1.什么是线程池
2.为什么要使用线程池
3.怎么使用线程池
4.自定义一个线程池
5.为什么不推荐使用系统自带的线程池
5.1线程池构造方法的参数和含义
5.1.1拒绝策略
5.2线程池的工作原理
5.3为什么不适用系统自带的线程池
补充:工厂模式
1.什么是线程池
在JDBC编程中,通过DataSource获取Connection连接的时候就已经用到了池的概念,当Java程序需要数据库连接的时候就从池中拿一个空闲的连接对象给Java程序,Java程序用完了连接之后就会返回给连接池。
线程池就是在池中放的是线程本身,当程序启动的时候就创建出若干个线程,如果有任务就处理,没有任务就等待。
百度百科的定义为:
线程池是一种多线程处理形式,处理过程中将任务添加到队列,然后在创建线程后自动启动这些任务。线程池线程都是后台线程。
2.为什么要使用线程池
使用线程池可以减少系统创建线程的损耗。
如下图:创建线程需要申请PCB
线程池的作用就是为了减少这些关于申请和释放PCB的操作,尽量保证我们的程序在用户态执行,不牵扯到硬件层面。
3.怎么使用线程池
JDK给我们提供了一些方法来创建线程池:
// 1. 用来处理大量短时间工作任务的线程池,如果池中没有可用的线程将创建新的线程,如果线程空闲60秒将收回并移出缓存ExecutorService cachedThreadPool = Executors.newCachedThreadPool();// 2. 创建一个操作无界队列且固定大小线程池ExecutorService fixedThreadPool = Executors.newFixedThreadPool(3);// 3. 创建一个操作无界队列且只有一个工作线程的线程池ExecutorService singleThreadExecutor = Executors.newSingleThreadExecutor();// 4. 创建一个单线程执行器,可以在给定时间后执行或定期执行。ScheduledExecutorService singleThreadScheduledExecutor = Executors.newSingleThreadScheduledExecutor();// 5. 创建一个指定大小的线程池,可以在给定时间后执行或定期执行。ScheduledExecutorService scheduledThreadPool = Executors.newScheduledThreadPool(3);// 6. 创建一个指定大小(不传入参数,为当前机器CPU核心数)的线程池,并行地处理任务,不保证处理顺序Executors.newWorkStealingPool();
这里使用第2个方法进行基本使用示例:
先创建一个线程池:
//创建一个线程池
ExecutorService threadPoll= Executors.newFixedThreadPool(3);
此时线程池中已经存在了一些创建好的线程,只需要往线程池中提交任务即可。
这里采用for循环,提交十个任务(打印“我是任务几”):
//提交任务到线程池for (int i = 0; i < 10; i++) {int taskId = i;threadPoll.submit(() -> {System.out.println("我是任务 " + taskId + ","+"Thread.currentThread().getName());});}
任务被提交到线程池后,任务就会被自动执行。
4.自定义一个线程池
1.可以提交任务到线程池,那么就会有一种数据结构来保存我们提交的任务,这里可以考虑用阻塞队列来保存任务。
2.创建线程池需要指定初始线程数量,这些线程不停的扫描阻塞队列,如果有任务就立即执行。可以考虑使用线程池对象的构造方法,接收要创建线程的数量,并在构造方法中完成线程的创建。
实现过程:
1.定义一个阻塞队列来保存我们的任务
//1.定义一个阻塞队列BlockingDeque<Runnable>queue=new LinkedBlockingDeque<>(3);
2.定义一个方法提交任务
//2.对外提供一个方法用来往队列中提交任务public void submit(Runnable task) throws InterruptedException {queue.put(task);}
3.定义构造方法
//3.构造方法,完成线程的创建,扫描队列,取出任务并执行public MyThreadPoll(int capacity){if(capacity<=0){throw new RuntimeException("线程数量不能小于0");}for (int i = 0; i < capacity; i++) {Thread thread=new Thread(()->{while(true) {try {//取出任务Runnable take = queue.take();//执行任务take.run();} catch (InterruptedException e) {throw new RuntimeException(e);}}});//启动线程thread.start();}}
测试一下代码:
public static void main(String[] args) throws InterruptedException {//创建自定义的线程池MyThreadPoll myThreadPoll=new MyThreadPoll(3);//往线程池中提交任务for (int i = 0; i < 10; i++) {int taskId=i;myThreadPoll.submit(()->{System.out.println("我是任务 " + taskId + ", " + Thread.currentThread().getName());});}}
执行成功,测试通过。
5.为什么不推荐使用系统自带的线程池
5.1线程池构造方法的参数和含义
通过工厂方法获取的线程池,最终都是ThreadPoolExecutor类的对象。
ThreadPoolEexecutor各参数含义:
corePoolSize:核心线程数,创建线程池时包含的最小线程数量
maximumPoolSize:最大线程数,也可以叫做临时线程数,当核心数不够用的时候,允许系统可以创建的最多线程数是多少
keepAliveTime:临时线程空闲的时长
TimeUnit unit:空闲的时间单位,和keepAliveTime配合使用
BlockingQueue<Runnable>workQueue:用来保存任务的阻塞队列
ThreadFactory:线程工厂,如何去创建线程,用系统默认的就可以
RejectedExecutionHandler:拒绝策略,触发的时机,当线程池处理不了过多的任务时触发
举例说明:
5.1.1拒绝策略
拒绝策略有4中,根据自己的业务场景选择合适的拒绝策略即可。
5.2线程池的工作原理
这七个参数搭配使用:
1.当任务添加到线程池中时,先判断任务数是否大于核心线程数
2.如果不大于直接执行,否则加入阻塞队列
3.当阻塞队列满了之后,会按指定的线程最大数创建临时线程
4.当阻塞队列满了,而且临时线程也创建完成,再提交任务时,执行拒绝策略
5.当任务减少,临时线程达到空闲时长时,会被回收
5.3为什么不适用系统自带的线程池
补充:工厂模式
工厂模式是我们最常用的实例化对象模式了,是用工厂方法代替new操作的一种模式。
先来看看一个代码示例:
定义一个Student类,定义有参构造
由于重载过程,参数列表相同而报错 。
使用工厂方法:
相关文章:

【JAVAEE】线程池基础知识⭐
目录 1.什么是线程池 2.为什么要使用线程池 3.怎么使用线程池 4.自定义一个线程池 5.为什么不推荐使用系统自带的线程池 5.1线程池构造方法的参数和含义 5.1.1拒绝策略 5.2线程池的工作原理 5.3为什么不适用系统自带的线程池 补充:工厂模式 1.什么是线程池…...

【源码解析】@ControllerAdvice实现异常捕获与响应增强处理的原理解析
全局异常处理 demo展示 Slf4j RestControllerAdvice public class GlobalExceptionAdvice {ExceptionHandler(RuntimeException.class)public R<Void> handleNotPermissionException(RuntimeException e, HttpServletRequest request) {String requestURI request.get…...

Visual Studio Code 插件的开发、调试及发布完整详细教程
本篇文章主要讲解:Vscode的拓展插件,从环境安装到生成项目文件再到调试及部署发布的完整开发教程。 日期:2023年5月10日 vscode 1.78.1 一、准备node环境及安装yo 项目初始化,优先安装yo、再通过yo创建code及插件项目。 基础条件 需要先安装node,且node环境已经正确安装…...

Qt音视频开发38-ffmpeg视频暂停录制的设计
一、前言 基本上各种播放器提供的录制视频接口,都是只有开始录制和结束录制两个,当然一般用的最多的也是这两个接口,但是实际使用过程中,还有一种可能需要中途暂停录制,暂停以后再次继续录制,将中间部分视频不需要录制,跳过这部分不需要的视频,而且录制的视频文件必须…...

bat脚本、dos命令
bat脚本 bat脚本就是DOS批处理脚本,就是将一系列DOS命令按照一定顺序排列而形成的集合,运行在windows命令行环境上。这个文件的每一行都是一条DOS命令 在命令提示下键入批处理文件的名称,或者双击该批处理文件,系统就会调用Cmd.…...

【星戈瑞】Sulfo-Cyanine5 mal红色荧光Cy5-maleimide
Sulfo-Cyanine5 mal是一种具有强荧光信号的染料,主要应用于生物荧光成像领域。它的化学式为C38H43KN4O9S2,分子量为803.00。这种染料具有良好的水溶性,可在水溶液中稳定存在。它的光学特性包括吸收峰位于646 nm和发射峰位于662 nm,…...

Dcip的学习1-计算器
文章目录 前言一、配置安装环境1.1 网址1.2 再次打开需要进行的操作1.3 NodeJS控制台的操作1.4 出现的页面 二、Dcip生成计算器2.1 软件的基本单位 - Unitform中添加内容 2.2 OnleftChange(); 前言 只是为方便学习,不做其他用途, 一、配置安装环境 1.1 …...
ChatGPT使用9大技巧详解
目录 技巧1:To Do and Not To Do 技巧2:增加示例 技巧3:使用引导词,引导模型输出特定内容...

随机变量X,分布函数X~F(x)的理解。
1.随机变量X 1.通常认知的"x"与随机变量X 我们通常意义上的 x 是自变量,y f(x) 中的自变量。 但是 X 更多意义是 对应法则 " f " ,X完整写法是 X(ω) ω ∈ Ω。 X这个对应法则,可以将样本点映射到实数轴上。 那么X这…...
11.构造器的查询.分块.聚合
学习要点: 1.构造器查询 2.分块.聚合 本节课我们来开始学习数据库的构造器查询以及分块和聚合查询。 一.构造器查询 1. table()方法引入相应的表,get()方法可以查询当前表的所有数据; //获取全部结果 $users DB::table(users)-&g…...

微服务保护——Sentinel
初识Sentinel 雪崩问题 微服务调用链路中的某个服务故障,引起整个链路中的所有微服务都不可用,这就是雪崩。 解决雪崩问题的常见方式有四种: 超时处理:设定超时时间,请求超过一定时间没有响应就返回错误信息,不会无休止等待舱壁…...
MySQL面试整理
https://houchen-study.oss-cn-hangzhou.aliyuncs.com/%E9%9D%A2%E8%AF%95/MySQL/MySQL%E9%9D%A2%E8%AF%95%E5%A4%A7%E5%85%A8%281%29.pdf 数据库基础知识 为什么要使用数据库? 什么是MySQL? 数据库的三大范式是什么? MySQL有关权限的表…...

Vscode C++环境配置
多文件编译 打开设置搜索coderunner 找到Executor Map 加入-I目录名 目录名/*.cpp 调试 点击调试以后会产生tasks.json文件,加入链接文件和库文件...
matlab小波去噪
本文将为您介绍如何利用MATLAB进行小波去噪处理,并应用于实际数据。小波去噪是一种通过对数据进行小波分解和重构的方法,有效地去除信号中的噪声,提高信号质量。该方法不仅广泛应用于信号处理、图像处理等领域,在实际生产和科研中…...
为什么要采用全网营销策略?全网营销有何优势?
现在市场上有很多全网营销公司,其实很多企业的经理人疑惑全网营销是要干什么?这些公司能干什么?这里小马识途营销顾问给大家做一个整体的解读。 全网营销,概括地说就是在整个互联网,利用各类互联网平台和工具对产品和服…...

prometheus实战之四:alertmanager的部署和配置
欢迎访问我的GitHub 这里分类和汇总了欣宸的全部原创(含配套源码):https://github.com/zq2599/blog_demos 本篇概览 本文是《prometheus实战》系列的第四篇,在《prometheus实战之三:告警规则》中曾经提到过,整个告警功能分为规则和…...
【Python】glob 包的介绍和使用
glob 是 Python 标准库中的一个模块,它提供了一种查找符合特定模式的路径名的方法,类似于命令行中的 glob 命令。glob 模块用于读取指定路径下的所有符合特定规律的文件名,非常适合用于读取文件夹中的文件列表和操作符合特定规律文件列表。 …...

剑指offer(C++)-JZ48:最长不含重复字符的子字符串(算法-动态规划)
作者:翟天保Steven 版权声明:著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处 题目描述: 请从字符串中找出一个最长的不包含重复字符的子字符串,计算该最长子字符串的长度。 数据范围…...
两阶段最小二乘法
两阶段最小二乘法 文章目录 两阶段最小二乘法[toc]1、ivreg包介绍2 、R语言实现 1、ivreg包介绍 R语言计量包ivreg用以解决线性回归模型的内生性问题。 描述:工具变量估计的线性模型通过两阶段最小二乘(2SLS) 回归或通过稳健回归M估计(2SM)或MM估计(2SMM)。主要的…...

ArcMap创建格网统计图
目录 前言 一、人口数据获取 来源一:中科院地理所公开数据集 来源二:WorldPop数据集 二、人口格网统计步骤 1.创建渔网 2.人口数据处理 2.1 栅格转点 2.2 空间插值——处理人口缺失数据 2.3 空间连接——渔网人口统计 总结 前言 在科研中&am…...
KubeSphere 容器平台高可用:环境搭建与可视化操作指南
Linux_k8s篇 欢迎来到Linux的世界,看笔记好好学多敲多打,每个人都是大神! 题目:KubeSphere 容器平台高可用:环境搭建与可视化操作指南 版本号: 1.0,0 作者: 老王要学习 日期: 2025.06.05 适用环境: Ubuntu22 文档说…...

深入剖析AI大模型:大模型时代的 Prompt 工程全解析
今天聊的内容,我认为是AI开发里面非常重要的内容。它在AI开发里无处不在,当你对 AI 助手说 "用李白的风格写一首关于人工智能的诗",或者让翻译模型 "将这段合同翻译成商务日语" 时,输入的这句话就是 Prompt。…...
Go 语言接口详解
Go 语言接口详解 核心概念 接口定义 在 Go 语言中,接口是一种抽象类型,它定义了一组方法的集合: // 定义接口 type Shape interface {Area() float64Perimeter() float64 } 接口实现 Go 接口的实现是隐式的: // 矩形结构体…...

2.Vue编写一个app
1.src中重要的组成 1.1main.ts // 引入createApp用于创建应用 import { createApp } from "vue"; // 引用App根组件 import App from ./App.vue;createApp(App).mount(#app)1.2 App.vue 其中要写三种标签 <template> <!--html--> </template>…...

学校招生小程序源码介绍
基于ThinkPHPFastAdminUniApp开发的学校招生小程序源码,专为学校招生场景量身打造,功能实用且操作便捷。 从技术架构来看,ThinkPHP提供稳定可靠的后台服务,FastAdmin加速开发流程,UniApp则保障小程序在多端有良好的兼…...

家政维修平台实战20:权限设计
目录 1 获取工人信息2 搭建工人入口3 权限判断总结 目前我们已经搭建好了基础的用户体系,主要是分成几个表,用户表我们是记录用户的基础信息,包括手机、昵称、头像。而工人和员工各有各的表。那么就有一个问题,不同的角色…...
根据万维钢·精英日课6的内容,使用AI(2025)可以参考以下方法:
根据万维钢精英日课6的内容,使用AI(2025)可以参考以下方法: 四个洞见 模型已经比人聪明:以ChatGPT o3为代表的AI非常强大,能运用高级理论解释道理、引用最新学术论文,生成对顶尖科学家都有用的…...

使用Spring AI和MCP协议构建图片搜索服务
目录 使用Spring AI和MCP协议构建图片搜索服务 引言 技术栈概览 项目架构设计 架构图 服务端开发 1. 创建Spring Boot项目 2. 实现图片搜索工具 3. 配置传输模式 Stdio模式(本地调用) SSE模式(远程调用) 4. 注册工具提…...
08. C#入门系列【类的基本概念】:开启编程世界的奇妙冒险
C#入门系列【类的基本概念】:开启编程世界的奇妙冒险 嘿,各位编程小白探险家!欢迎来到 C# 的奇幻大陆!今天咱们要深入探索这片大陆上至关重要的 “建筑”—— 类!别害怕,跟着我,保准让你轻松搞…...

【C++】纯虚函数类外可以写实现吗?
1. 答案 先说答案,可以。 2.代码测试 .h头文件 #include <iostream> #include <string>// 抽象基类 class AbstractBase { public:AbstractBase() default;virtual ~AbstractBase() default; // 默认析构函数public:virtual int PureVirtualFunct…...