并发编程——4.线程池
这篇文章我们来讲一下线程池的相关内容
目录
1.什么是线程池
1.1为什么要用线程池
1.2线程池的优势
2.线程池的使用
3.线程池的关闭
4.线程池中的execute和submit方法的一些区别
5.线程池的参数和原理
6.自定义线程池
7.总结
1.什么是线程池
1.1为什么要用线程池
首先,我们要清楚这样的一个问题,我们为什么要用线程池?
思考下面的这样的一个场景:某线上商城做秒杀活动,1秒内有10万个请求打来,我们的服务器能在1秒内创建10万个线程吗?显然是不合理的。其次,我们使用线程时会伴随着线程的创建和消耗,当线程数量很多时,这会占用机器的资源,所以这也不合理。为了解决上面提到的问题,所以我们使用了线程池。
如果并发的线程数量很多,并且每个线程都是执行一个时间很短的任务就结束了,这样频繁创建线程就会大大降低系统的效率,因为频繁创建线程和销毁线程需要时间。
那么有没有一种办法使得线程可以复用,就是执行完一个任务,并不被销毁,而是可以继续执行其他的任务?在Java中可以通过线程池来达到这样的效果。
线程池:其实就是一个容纳多个线程的容器,其中的线程可以反复使用,省去了频繁创建线程对象的操作,无需反复创建线程而消耗过多资源。
1.2线程池的优势
线程池做的工作主要是控制运行的线程数量,处理过程中将任务放入队列,然后在线程创建后启动这些任务,如果线程数量超过了最大数量,超出数量的线程排队等候,等其他线程执行完毕,再从队列中取出任务来执行。
它的主要特点为:线程复用;控制最大并发数;管理线程。
线程池的优势:
- 第一:降低资源消耗。通过重复利用已创建的线程降低线程创建和销毁造成的销耗。
- 第二:提高响应速度。当任务到达时,任务可以不需要等待线程创建就能立即执行。
- 第三:提高线程的可管理性。线程是稀缺资源,如果无限制的创建,不仅会销耗系统资源,还会降低系统的稳定性,使用线程池可以进行统一的分配,调优和监控
2.线程池的使用
对于线程池的原理不是很清楚的情况下,很有可能配置的线程池不是较优的,因此在java.util.concurrent . Executors 线程工厂类里面提供了一些静态工厂,生成一些常用的线程池。官方建议使用 Executors工程类来创建线程池对象。Java类库提供了许多静态方法来创建一个线程池:
Executors类中创建线程池的方法如下:
- a、newFixedThreadPool创建一个固定长度的线程池,当到达线程最大数量时,线程池的规模将不再变化。
- b、newCachedThreadPool创建一个可缓存的线程池,如果当前线程池的规模超出了处理需求,将回收空的线程;当需求增加时,会增加线程数量;线程池规模无限制。
- c、newSingleThreadPoolExecutor创建一个单线程的Executor,确保任务对了,串行执行
- d、newScheduledThreadPool创建一个固定长度的线程池,但是是可以定时的进行调度
下面我们就通过代码来看一下各种方法的使用
这个其实没啥好说的,因为这个用的是Java中提供的线程池的工具类,是很简单的,直接用就行。
3.线程池的关闭
下面看一下线程池的关闭
我们创建一个线程池,在使用完毕后,一定要关闭线程池,关闭线程池的代码要放在finally里面,目的是为了避免程序出错,导致线程池没有关闭。我们关闭线程池后,线程池中正在执行的线程不会立刻被停止,它会等到该线程执行完毕后再关闭,即线程池是会等待线程池中所有的线程都被执行完才关闭。
为什么要关闭线程池?为了避免线程池中的线程一直占用系统资源,造成内存泄漏
下面看一下代码:
注意区分shutdown和shutdownNow二者的区别!
4.线程池中的execute和submit方法的一些区别
下面,我们来看一下线程池中的execute方法和submit方法的区别
区别一:
execute方法的入参只能是Runnable,而submit方法的入参可以是Runnable,也可以是Callable
下面看一下代码:
区别二:
execute的返回值为void类型,而submit的返回值为Future类型
下面看一下代码:
区别三:
execute 会在子线程中抛出异常,但是主线程中捕捉不到。而submit是不会立刻抛出异常,它会将此异常暂时存起来,如果想要将该异常抛出,需要用Future对象接收submit的返回值,然后调用Future的get方法。
下面看一下代码:
5.线程池的参数和原理
下面,我们来看一下线程池的参数和原理
首先,我们看一下我们四种创建线程池的方式,然后Ctrl+单击,看一下它的源码:
我们会发现,这四种创建线程池的源码基本相同,都是返回了一个ThreadPoolExecutor对象,区别就在于里面的参数不一样。我们再单击看一下ThreadPoolExecutor的源码:
如上图所示,下面我们来介绍一下ThreadPoolExecutor中参数的意思
- corePoolSize:核心线程数量(这个不用过多解释)
- maximumPoolSize:最大线程数量(就是这个线程池最大能开辟的线程数量)
- KeepAliveTime:非核心线程的空闲状态的存活时间(就是如何该线程不是核心线程,并且它是空闲的,那么它的存活时间是多少,是long类型的数字)
- unit:非核心线程的空闲状态的存活时间的单位
- workQueue:工作队列(阻塞队列)
- threadFactory:线程工程(创建线程用的,就是一个接口,然后平时使用的就是创建默认线程)
- handler:拒绝策略(就是当我们的核心线程数,阻塞队列,最大线程数都满了的情况的下,还有线程来,那么就按照这个拒绝策略进行拒绝)
下面就整个流程进行一下梳理:
首先,我们进行提交任务,然后程序会判断你提交的任务数量是否大于你创建线程池的核心线程数量,如何不大于,OK,那么程序开始创建线程,执行任务;如果大于了核心线程数量,那么多余的任务进入阻塞队列里面进行等待,如果这时阻塞队列满了,那么程序会判断你创建线程池的最大线程数量是否满了,如果没满,那么程序根据最大线程数量来创建线程,执行任务,如果这时最大线程数量也满了,那么就执行拒绝策略,多余的任务就被拒绝了,不接受了。
这里对最大线程数量和非核心线程空闲状态存活时间进行一下场景解释:
假设现在有一个促销秒杀活动,比如双十一、618等。你的网站日常活跃用户只有5000万,所以你的程序的核心线程数设置为5000万,然后最大线程数设置为7000万,但是在活动促销的那两个小时,你的网站的活跃用户达到了1亿,那么你就不可能再把最大线程数设置为7000万了,而是设置为1亿,但是你只有那两个小时的用户活跃数是1亿,所以你不可能一直让那1亿个线程开着,所以你将非核心线程的空闲存活时间设置为2h,时间一过,如果该非核心线程是空闲状态,那么该线程就被销毁,这样就可以节约资源了。
下面看一下拒绝策略:
这个了解一下就可以了。
6.自定义线程池
上面我们学习了线程池的核心源码和其中的一些参数的含义,下面我们来书写一个自定义的线程池,然后我们再来具体的分析一下
代码如下:
然后,我们来看一下输出结果:
下面再用一张图来解释一下吧:
其实这是很好理解的
7.总结
这篇文章我们主要介绍了一下线程池的相关内容,包括什么是线程池,怎么创建或者说怎么使用线程池,线程池的注意点,线程池中两个方法的区别,以及如何自定义线程池(线程池的源码会在源码篇章中写),这部分是比较重要的内容,要掌握。
相关文章:

并发编程——4.线程池
这篇文章我们来讲一下线程池的相关内容 目录 1.什么是线程池 1.1为什么要用线程池 1.2线程池的优势 2.线程池的使用 3.线程池的关闭 4.线程池中的execute和submit方法的一些区别 5.线程池的参数和原理 6.自定义线程池 7.总结 1.什么是线程池 1.1为什么要用线程池 首…...

阿里云魔搭发起“ModelScope-Sora开源计划”,将为中国类Sora模型开发提供一站式工具链
在2024年3月23日的全球开发者先锋大会上,阿里云的魔搭社区宣布了一个新计划:“ModelScope-Sora开源计划”。这个计划旨在通过开源方式,帮助中国在Sora模型类型上做出更多创新。这个计划提供了一整套工具,包括处理数据的工具、多模…...

大模型与数据分析:探索Text-to-SQL
当今大模型如此火热,作为一名数据同学,持续在关注LLM是如何应用在数据分析中的,也关注到很多公司推出了AI数智助手的产品,比如火山引擎数智平台VeDI—AI助手、 Kyligence Copilot AI数智助理、ThoughtSpot等,通过接入人…...

Unity VisionOS开发流程
Unity开发环境 Unity Pro, Unity Enterprise and Unity Industry 国际版 Mac Unity Editor(Apple silicon) visionOS Build Support (experimental) 实验版 Unity 2022.3.11f1 NOTE: 国际版与国服版Pro账通用,需要激活Pro的许可证。官方模板v0.6.2,非Pro版本会打…...

聊聊k8s服务发现的优缺点
序 本文主要研究一下使用k8s服务发现的优缺点 spring cloud vs kubernetes 这里有张spring cloud与kubernetes的对比,如果将微服务部署到kubernetes上面,二者有不少功能是重复的,可否精简。 这里主要是讲述一下如果不使用独立的服务发现&am…...
Tomcat是如何处理并发请求的?
Tomcat处理请求流程: Tomcat是采用了扩展JDK线程池的方案 :先启动若干数量的线程,并让这些线程都处于睡眠状态,当客户端有一个新请求时,就会唤醒线程池中的某一个睡眠线程,让它来处理客户端的这个请求,当处…...

H12-831_561
单选题561、如图所示,R1使用Loopback0接口(IP地址为10.0.1.1/32)与R2的物理接口(IP地址为10.0.12.2/24)建立EBGP邻居关系,以下描述中正确的是哪一项? A.无需在R1和R2的BGP进程下指定ebgp-max-hop B.在R2的BGP进程下配置peer 10.0.1.1 ebgp-max-hop 2,且…...

Java23种常见设计模式汇总
七大原则网站地址:设计模式7大原则+类图关系-CSDN博客 创建型设计模式:创建型设计模式合集-CSDN博客 七大结构型设计模式:7大结构型设计模式-CSDN博客 11种行为型设计模式: 11种行为型模式(上࿰…...

神经网络与深度学习(一)
线性回归 定义 利用数理统计中回归分析,来确定两种或两种以上变量间相互依赖的定量关系的一种统计分析方法 要素 训练集(训练数据)输出数据拟合函数数据条目数 场景 预测价格(房屋、股票等)、预测住院时间&#…...

算法学习——LeetCode力扣图论篇2
算法学习——LeetCode力扣图论篇2 1020. 飞地的数量 1020. 飞地的数量 - 力扣(LeetCode) 描述 给你一个大小为 m x n 的二进制矩阵 grid ,其中 0 表示一个海洋单元格、1 表示一个陆地单元格。 一次 移动 是指从一个陆地单元格走到另一个相…...

大数据设计为何要分层,行业常规设计会有几层数据
大数据设计通常采用分层结构的原因是为了提高数据管理的效率、降低系统复杂度、增强数据质量和可维护性。这种分层结构能够将数据按照不同的处理和应用需求进行分类和管理,从而更好地满足不同层次的数据处理和分析需求。行业常规设计中,数据通常按照以下…...

css3之2D转换transform
2D转换transform 一.移动(translate)(中间用,隔开)二.旋转(rotate)(有单位deg)1.概念2.注意点3.转换中心点(transform-origin)(中间用空格)4.一些例子(css三角和旋转) 三…...
pytest中文使用文档----6临时目录和文件
1. 相关的fixture 1.1. tmp_path1.2. tmp_path_factory1.3. tmpdir1.4. tmpdir_factory1.5. 区别 2. 默认的基本临时目录 1. 相关的fixture 1.1. tmp_path tmp_path是一个用例级别的fixture,其作用是返回一个唯一的临时目录对象(pathlib.Path…...

从0开始搭建基于VUE的前端项目
准备与版本 安装nodejs(v20.11.1)安装vue脚手架(vue/cli 5.0.8) ,参考(https://cli.vuejs.org/zh/)vue版本(2.7.16),vue2的最后一个版本 初始化项目 创建一个git项目(可以去gitee/github上创建ÿ…...

elementUI this.$msgbox msgBox自定义 样式自定义 富文本
看这个效果是不是很炫?突出重点提示内容,对于用户交互相当的棒! 下来说说具体实现: let self = this const h = self.$createElement; this.$msgbox({title: null,message: h("p", {style: "margin-top:10px"}, [h("i", {class: "el-i…...
Lua与Python区别
Lua和Python都是流行的编程语言,但它们在设计哲学、应用领域和性能特点上有所不同。以下是Lua和Python之间的对比: 1. **设计哲学**: - Lua被设计为一个轻量级的嵌入式脚本语言,重点在于简单性和效率。它有一个小巧的标准库,通…...

Python学习(二)
数据容器 数据容器根据特点的不同,如: 是否支持重复元素是否可以修改是否有序,等 分为5类,分别是: 列表(list)、元组(tuple)、字符串(str)、集…...

管理阿里云服务器ECS -- 网站选型和搭建
小云:我已经学会了如何登录云服务器ECS了,但是要如何搭建网站呢? 老王:目前有很多的个人网站系统软件,其中 WordPress 是使用非常广泛的一款,而且也可以把 WordPress 当作一个内容管理系统(CMS…...

WPF中继承ItemsControl子类控件数据模板获取选中属性
需求场景 列表类控件,如 ListBox、ListView、DataGrid等。显示的行数据中,部分内容依靠选中时触发控制,例如选中行时行记录复选,部分列内容控制显隐。 案例源码以ListView 为例。 Xaml 部分 <ListView ItemsSource"{Bi…...

Android卡顿掉帧问题分析之实战篇
本文将结合典型实战案例,分析常见的造成卡顿等性能问题的原因。从系统工程师的总体角度来看 ,造成卡顿等性能问题的原因总体上大致分为三个大类:一类是流程执行异常;二是系统负载异常;三是编译问题引起。 1 流程执行异…...

wordpress后台更新后 前端没变化的解决方法
使用siteground主机的wordpress网站,会出现更新了网站内容和修改了php模板文件、js文件、css文件、图片文件后,网站没有变化的情况。 不熟悉siteground主机的新手,遇到这个问题,就很抓狂,明明是哪都没操作错误&#x…...
后进先出(LIFO)详解
LIFO 是 Last In, First Out 的缩写,中文译为后进先出。这是一种数据结构的工作原则,类似于一摞盘子或一叠书本: 最后放进去的元素最先出来 -想象往筒状容器里放盘子: (1)你放进的最后一个盘子(…...
反向工程与模型迁移:打造未来商品详情API的可持续创新体系
在电商行业蓬勃发展的当下,商品详情API作为连接电商平台与开发者、商家及用户的关键纽带,其重要性日益凸显。传统商品详情API主要聚焦于商品基本信息(如名称、价格、库存等)的获取与展示,已难以满足市场对个性化、智能…...

相机Camera日志实例分析之二:相机Camx【专业模式开启直方图拍照】单帧流程日志详解
【关注我,后续持续新增专题博文,谢谢!!!】 上一篇我们讲了: 这一篇我们开始讲: 目录 一、场景操作步骤 二、日志基础关键字分级如下 三、场景日志如下: 一、场景操作步骤 操作步…...

【JVM】- 内存结构
引言 JVM:Java Virtual Machine 定义:Java虚拟机,Java二进制字节码的运行环境好处: 一次编写,到处运行自动内存管理,垃圾回收的功能数组下标越界检查(会抛异常,不会覆盖到其他代码…...

【单片机期末】单片机系统设计
主要内容:系统状态机,系统时基,系统需求分析,系统构建,系统状态流图 一、题目要求 二、绘制系统状态流图 题目:根据上述描述绘制系统状态流图,注明状态转移条件及方向。 三、利用定时器产生时…...
sqlserver 根据指定字符 解析拼接字符串
DECLARE LotNo NVARCHAR(50)A,B,C DECLARE xml XML ( SELECT <x> REPLACE(LotNo, ,, </x><x>) </x> ) DECLARE ErrorCode NVARCHAR(50) -- 提取 XML 中的值 SELECT value x.value(., VARCHAR(MAX))…...

Maven 概述、安装、配置、仓库、私服详解
目录 1、Maven 概述 1.1 Maven 的定义 1.2 Maven 解决的问题 1.3 Maven 的核心特性与优势 2、Maven 安装 2.1 下载 Maven 2.2 安装配置 Maven 2.3 测试安装 2.4 修改 Maven 本地仓库的默认路径 3、Maven 配置 3.1 配置本地仓库 3.2 配置 JDK 3.3 IDEA 配置本地 Ma…...

Selenium常用函数介绍
目录 一,元素定位 1.1 cssSeector 1.2 xpath 二,操作测试对象 三,窗口 3.1 案例 3.2 窗口切换 3.3 窗口大小 3.4 屏幕截图 3.5 关闭窗口 四,弹窗 五,等待 六,导航 七,文件上传 …...

C++实现分布式网络通信框架RPC(2)——rpc发布端
有了上篇文章的项目的基本知识的了解,现在我们就开始构建项目。 目录 一、构建工程目录 二、本地服务发布成RPC服务 2.1理解RPC发布 2.2实现 三、Mprpc框架的基础类设计 3.1框架的初始化类 MprpcApplication 代码实现 3.2读取配置文件类 MprpcConfig 代码实现…...