【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…...

51c自动驾驶~合集58
我自己的原文哦~ https://blog.51cto.com/whaosoft/13967107 #CCA-Attention 全局池化局部保留,CCA-Attention为LLM长文本建模带来突破性进展 琶洲实验室、华南理工大学联合推出关键上下文感知注意力机制(CCA-Attention),…...
DeepSeek 赋能智慧能源:微电网优化调度的智能革新路径
目录 一、智慧能源微电网优化调度概述1.1 智慧能源微电网概念1.2 优化调度的重要性1.3 目前面临的挑战 二、DeepSeek 技术探秘2.1 DeepSeek 技术原理2.2 DeepSeek 独特优势2.3 DeepSeek 在 AI 领域地位 三、DeepSeek 在微电网优化调度中的应用剖析3.1 数据处理与分析3.2 预测与…...

关于nvm与node.js
1 安装nvm 安装过程中手动修改 nvm的安装路径, 以及修改 通过nvm安装node后正在使用的node的存放目录【这句话可能难以理解,但接着往下看你就了然了】 2 修改nvm中settings.txt文件配置 nvm安装成功后,通常在该文件中会出现以下配置&…...

html-<abbr> 缩写或首字母缩略词
定义与作用 <abbr> 标签用于表示缩写或首字母缩略词,它可以帮助用户更好地理解缩写的含义,尤其是对于那些不熟悉该缩写的用户。 title 属性的内容提供了缩写的详细说明。当用户将鼠标悬停在缩写上时,会显示一个提示框。 示例&#x…...

JVM虚拟机:内存结构、垃圾回收、性能优化
1、JVM虚拟机的简介 Java 虚拟机(Java Virtual Machine 简称:JVM)是运行所有 Java 程序的抽象计算机,是 Java 语言的运行环境,实现了 Java 程序的跨平台特性。JVM 屏蔽了与具体操作系统平台相关的信息,使得 Java 程序只需生成在 JVM 上运行的目标代码(字节码),就可以…...

push [特殊字符] present
push 🆚 present 前言present和dismiss特点代码演示 push和pop特点代码演示 前言 在 iOS 开发中,push 和 present 是两种不同的视图控制器切换方式,它们有着显著的区别。 present和dismiss 特点 在当前控制器上方新建视图层级需要手动调用…...

在 Spring Boot 中使用 JSP
jsp? 好多年没用了。重新整一下 还费了点时间,记录一下。 项目结构: pom: <?xml version"1.0" encoding"UTF-8"?> <project xmlns"http://maven.apache.org/POM/4.0.0" xmlns:xsi"http://ww…...

算法打卡第18天
从中序与后序遍历序列构造二叉树 (力扣106题) 给定两个整数数组 inorder 和 postorder ,其中 inorder 是二叉树的中序遍历, postorder 是同一棵树的后序遍历,请你构造并返回这颗 二叉树 。 示例 1: 输入:inorder [9,3,15,20,7…...
Python爬虫实战:研究Restkit库相关技术
1. 引言 1.1 研究背景与意义 在当今信息爆炸的时代,互联网上存在着海量的有价值数据。如何高效地采集这些数据并将其应用于实际业务中,成为了许多企业和开发者关注的焦点。网络爬虫技术作为一种自动化的数据采集工具,可以帮助我们从网页中提取所需的信息。而 RESTful API …...

DAY 45 超大力王爱学Python
来自超大力王的友情提示:在用tensordoard的时候一定一定要用绝对位置,例如:tensorboard --logdir"D:\代码\archive (1)\runs\cifar10_mlp_experiment_2" 不然读取不了数据 知识点回顾: tensorboard的发展历史和原理tens…...