并发编程---线程池(六)
阻塞队列的应⽤——线程池
- 一 线程池基本概念
- 二 线程池三种常⽤创建⽅式
- 2.1.newFixedThreadPool线程池:
- 2.2.newSingleThreadExecutor线程池:
- 2.3.newCachedThreadPool线程池:
- 2.4. 线程池代码演示
- 三 线程池创建的七个参数
- 四 线程池底层原理
- 理解:
- 案例图:
- 原理图:
- 流程图:
- 线程池使用注意:
- 五 线程池的拒绝策略
- AbortPolicy拒绝策略
- CallerRunsPolicy拒绝策略
- DiscardOldestPolicy拒绝策略
- DiscardPolicy拒绝策略
- 六 实际⽣产使⽤哪⼀个线程池?
- 七 ⾃定义线程池参数选择
一 线程池基本概念
概念: 线程池主要是控制运⾏线程的数量,将待处理任务放到等待队列,然后创建线程执⾏这些任务。 如果超过了最⼤线程数,则等待。
为什么⽤线程池?
10年前单核CPU电脑,假的多线程,像⻢戏团⼩丑玩多个球,CPU需要来回切换。
现在是多核电脑,多个线程各⾃跑在独⽴的CPU上,不⽤切换效率⾼。
线程池的优点:
线程池做的⼯作主要是控制运⾏的线程数量,处理过程中将任务放⼊队列,然后在线程创建后启动这些任务,如果线程数量超过了最⼤数量,超出数量的线程排队等候,等其他线程执⾏完毕,再从队列中取出任务来执⾏。
线程池的主要特点为:线程复⽤;控制最⼤并发数;管理线程。
- 线程复⽤:不⽤⼀直new新线程,重复利⽤已经创建的线程来降低线程的创建和销毁开销,节省系统资源。
- 提⾼响应速度:当任务达到时,不⽤创建新的线程,直接利⽤线程池的线程。
- 管理线程:可以控制最⼤并发数,控制线程的创建等。
体系: Executor→→ExecutorService→AbstractExecutorService→ThreadPoolExecutor。
ThreadPoolExecutor是线程池创建的核⼼类。类似Arrays、Collections工具类,Executor也有自己的工具类Executors。
二 线程池三种常⽤创建⽅式
2.1.newFixedThreadPool线程池:
使⽤ LinkedBlockingQueue实现,定⻓线程池。
特点:执⾏⻓期任务性能好,创建⼀个线程池,⼀池有N个固定的线程,有固定线程数的线程
2.2.newSingleThreadExecutor线程池:
使⽤ LinkedBlockingQueue实现,⼀池只有⼀个线程。
特点:⼀个任务⼀个任务的执⾏,⼀池⼀线程
2.3.newCachedThreadPool线程池:
使⽤ SynchronousQueue实现,变⻓线程池。
特点:执⾏很多短期异步任务,线程池根据需要创建新线程,但在先前构建的线程可⽤时将重⽤他们。 可扩容,遇强则强
2.4. 线程池代码演示
任务类
模拟十个客户来办理业务
private static void threadPoolTask(ExecutorService threadPool) {//模拟有10个顾客来办理业务try {for (int i = 1; i <= 10; i++) {threadPool.execute(() -> {System.out.println(Thread.currentThread().getName() + "\t办理业务");try {TimeUnit.SECONDS.sleep(1);} catch (InterruptedException e) {e.printStackTrace();}});}} catch (Exception e) {e.printStackTrace();} finally {threadPool.shutdown();}}
- newFixedThreadPool线程池
创建线程数为5,观察结果发现5个线程一起执行
//一个池子有5个工作线程,类似银行有5个受理窗口threadPoolTask(Executors.newFixedThreadPool(5));
- newSingleThreadExecutor线程池
创建newSingleThreadExecutor线程池,观察结果发现只有一个线程可以使用。
System.out.println("======Single Thread Pool=========");// //一个池子有1个工作线程,类似银行有1个受理窗口threadPoolTask( Executors.newSingleThreadExecutor() );
- newCachedThreadPool线程池:
创建newCachedThreadPool,观察结果有10个客户,就有<=10个线程执行任务。有可能业务员办事快,接着又给其他客户办理业务
System.out.println("=====Cached Thread Pool=======");// //不定量线程,一个池子有N个工作线程,类似银行有N个受理窗口threadPoolTask( Executors.newCachedThreadPool() );
问题:
上述我们使用10个客户来模拟,如果用100个呢,我们来观察结果
三 线程池创建的七个参数
参数 | 意义 |
---|---|
corePoolSize | 线程池中的常驻核⼼线程数 |
maximumPoolSize | 线程池中能够容纳同时并发的最⼤线程数 ,此值必须⼤于等于1 |
keepAliveTime | 多余的空闲线程的存活时间 ,当前池中线程数量超过corePoolSize时,当空闲时间达到keepAliveTime时,多余线程会被销毁直到只剩下corePoolSize个线程为⽌ |
unit | keepAliveTime存活时间的单位 |
workQueue | 任务队列 ,存放已提交但尚未执⾏的任务 |
threadFactory | 表示⽣成线程池中⼯作线程的线程⼯⼚ ,⽤于创建线程,⼀般默认的即可 |
handler | 拒绝策略 ,表示当队列满了,并且⼯作线程⼤于等于线程池的最⼤线程数(maximumPoolSize)时,如何来拒绝请求执⾏的runnable的策略 |
四 线程池底层原理
理解:
线程池的创建参数,就像⼀个银⾏。
corePoolSize
就像银⾏的“当值窗⼝“,⽐如今天有2位柜员在受理客户请求(任务)。- 如果超过2个客户,那么新的客户就会在等候区(等待队列
workQueue
)等待。 - 当等候区也满了,这个时候就要开启“加班窗⼝”,让其它3位柜员来加班,此时达到最⼤窗⼝
maximumPoolSize
,为5个。 - 如果开启了所有窗⼝,等候区依然满员,此时就应该启动”拒绝策略
handler
,告诉不断涌⼊的客户, 叫他们不要进⼊,已经爆满了。 - 由于不再涌⼊新客户,办完事的客户增多,窗⼝开始空闲,这个时候就通过
keepAlivetTime
将多余的3个”加班窗⼝“取消,恢复到2个”当值窗⼝“
案例图:
原理图:
上⾯银⾏的例⼦,实际上就是线程池的⼯作原理。
流程图:
流程:
- 在创建了线程池后,开始等待请求。
- 当调⽤
execute()
⽅法添加⼀个请求任务时,线程池会做出如下判断:
2.1 如果正在运⾏的线程数量⼩于corePoolSize
,那么⻢上创建核⼼线程运⾏执⾏这个任务;
2.2 如果正在运⾏的线程数量⼤于或等于corePoolSize
,那么将这个任务放⼊队列;
2.3 如果这个时候等待队列已满,且正在运⾏的线程数量⼩于maximumPoolSize
,那么还是要创
建⾮核⼼线程⽴刻运⾏这个任务;
2.4 如果这个时候等待队列已满,且正在运⾏的线程数量⼤于或等于maximumPoolSize
,那么线程池会启动饱和拒绝策略来执⾏。- 当⼀个线程完成任务时,它会从等待队列中取出下⼀个任务来执⾏。
- 当⼀个线程⽆事可做超过⼀定的时间(
keepAliveTime
)后,线程会判断:
如果当前运⾏的线程数⼤于corePoolSize
,那么这个⾮核⼼线程就被停掉。当线程池的所有任
务完成后,它最终会收缩到corePoolSize
的⼤⼩。
线程池使用注意:
《Java 开发⼿册》是阿⾥巴巴集团技术团队:
五 线程池的拒绝策略
当等待队列满时,且达到最⼤线程数,再有新任务到来,就需要启动拒绝策略。JDK提供了四种拒绝策
略,分别是:
AbortPolicy
:默认的策略,直接抛出 RejectedExecutionException异常,阻⽌系统正常运⾏。CallerRunsPolicy
:既不会抛出异常,也不会终⽌任务,⽽是将任务返回给调⽤者,从⽽降低新任务的流量。DiscardOldestPolicy
:抛弃队列中等待最久的任务,然后把当前任务加⼊队列中尝试再次提交任务。DiscardPolicy
:该策略默默地丢弃⽆法处理的任务,不予任何处理也不抛出异常。如果允许任务丢失,这是最好的⼀种策略。
AbortPolicy拒绝策略
CallerRunsPolicy拒绝策略
DiscardOldestPolicy拒绝策略
DiscardPolicy拒绝策略
六 实际⽣产使⽤哪⼀个线程池?
单⼀、可变、定⻓都不⽤!原因就是FixedThreadPool
和 SingleThreadExecutor
底层都是⽤ LinkedBlockingQueue
实现的,这个队列最⼤⻓度为 Integer.MAX_VALUE
,显然会导致OOM
。所以实际⽣产⼀般⾃⼰通过的7个参数,⾃定义线程池
System.out.println("=====Custom Thread Pool=======");threadPoolTask( new ThreadPoolExecutor(2,5,1L,TimeUnit.SECONDS,new LinkedBlockingQueue<>(3),Executors.defaultThreadFactory(),new ThreadPoolExecutor.DiscardPolicy()));
结果分析
七 ⾃定义线程池参数选择
对于CPU密集型任务,最⼤线程数是CPU线程数+1。
对于IO密集型任务(文件上传下载),尽量多配点,可以是CPU线程数*2,或者CPU线程数/(1-阻塞系数)。
IO密集型,即该任务需要⼤量的IO,即⼤量的阻塞。
在单线程上运⾏IO密集型的任务会导致浪费⼤量的CPU运算能⼒浪费在等待。
所以在IO密集型任务中使⽤多线程可以⼤⼤的加速程序运⾏,及时在单核CPU上,这种加速主要就是利⽤了被浪费掉的阻塞时间。
IO密集型时,⼤部分线程都阻塞,故需要多配置线程数:
**参考公式:**CPU核数 / 1 - 阻塞系数 阻塞系数在 0.8~0.9 之间
⽐如 8 核 CPU:8/1 - 0.9 = 80个线程数
相关文章:

并发编程---线程池(六)
阻塞队列的应⽤——线程池一 线程池基本概念二 线程池三种常⽤创建⽅式2.1.newFixedThreadPool线程池:2.2.newSingleThreadExecutor线程池:2.3.newCachedThreadPool线程池:2.4. 线程池代码演示三 线程池创建的七个参数四 线程池底层原理理解&…...
【Java实战】不会还有人用if else进行参数校验吧
当请求参数很多,几乎每一个参数都需要后端去兜底校验时,你还在写if else去判断参数是否为空吗??要校验为空的参数三四个还好,要是十几个,业务逻辑还没开始就写二三十行代码开始堆山了嘛,教给大家…...
深度学习部署(十六): CUDA RunTime API _vector-add 使用cuda核函数实现向量加法
1. 知识点 nthreads的取值,不能大于block能取值的最大值。一般可以直接给512、256,性能就是比较不错的 (input_size block_size - 1) / block_size;是向上取整 对于一维数组时,采用只定义layout的x维度,若处理的是二维ÿ…...
堆结构的两个应用
堆排序 堆结构很大的一个用处,就是用于堆排序了,堆排序的时间复杂度是O(n∗log2n)O(n*log_2n)O(n∗log2n)量级的,在众多排序算法中所处的地位也是高手级别的了。 但很多人在使用堆排序的时候,首先认为我必须得有一个堆数据结构…...
Java中的 static
1 static 静态变量 1.1 静态变量的使用 static变量也称作静态变量,也叫做类变量 静态变量被所有的对象所共享,在内存中只有一个副本 当且仅当在类初次加载时会被初始化 静态变量属于类 通过类名就可以直接调用静态变量 也可以通过对象名.静态变量…...

基于Vision Transformer的图像去雾算法研究与实现(附源码)
基于Vision Transformer的图像去雾算法研究与实现 0. 服务器性能简单监控 \LOG_USE_CPU_MEMORY\文件夹下的use_memory.py文件可以实时输出CPU使用率以及内存使用率,配合nvidia-smi监控GPU使用率 可以了解服务器性能是否足够;运行时在哪一步使用率突然…...
服务器相关常用的命令
cshell语法 https://www.doc88.com/p-4985161471426.html domainname命令 1)查看当前系统域名 domainname2)设置并查看当前系统域名 domainname example.com3)显示主机ip地址 domainname -Iwhich命令 which 系统命令在 PATH 变量指定的…...

今天是国际数学日,既是爱因斯坦的生日又是霍金的忌日
目录 一、库函数计算 π 二、近似值计算 π 三、无穷级数计算 π 四、割圆术计算 π 五、蒙特卡罗法计算 π 六、计算800位精确值 从2020年开始,每年的3月14日又被定为国际数学日,是2019年11月26日联合国教科文组织第四十届大会上正式宣布…...

Qt Quick - StackLayout 堆布局
StackLayout 堆布局一、概述二、attached 属性三、例子1. 按钮切换 StackLayout 页面一、概述 StackLayout 其实就是说,在同一个时刻里面,只有一个页面是展示出来的,类似QStackWidget 的功能,主要就是切换界面的功能。这个类型我…...

C/C++网络编程笔记Socket
https://www.bilibili.com/video/BV11Z4y157RY/?vd_sourced0030c72c95e04a14c5614c1c0e6159b上面链接是B站的博主教程,源代码来自上面视频,侵删,这里只是做笔记,以供复习和分享。上一篇博客我记录了配置环境并且跑通了࿰…...

RK3568平台开发系列讲解(网络篇)什么是Socket套接字
🚀返回专栏总目录 文章目录 一、什么是socket ?二、socket 理解为电话机三、socket 的发展历史四、套接字地址格式4.1、通用套接字地址格式4.2、IPv4 套接字格式地址4.3、IPv6 套接字地址格式4.4、几种套接字地址格式比较沉淀、分享、成长,让自己和他人都能有所收获!😄 …...
2022年全国职业院校技能大赛(中职组)网络安全竞赛试题——渗透测试解析(详细)
渗透测试 任务环境说明: 服务器场景:Server9服务器场景操作系统:未知(关闭连接)系统用户名:administrator密码:123456通过本地PC中渗透测试平台Kali对靶机场景进行系统服务及版本扫描渗透测试,以xml格式向指定文件输出信息(使用工具Nmap),将以xml格式向指定文件输出…...

尚融宝03-mybatis-plus基本CRUD和常用注解
目录 一、通用Mapper 1、Create 2、Retrieve 3、Update 4、Delete 二、通用Service 1、创建Service接口 2、创建Service实现类 3、创建测试类 4、测试记录数 5、测试批量插入 三、自定义Mapper 1、接口方法定义 2、创建xml文件 3、测试条件查询 四、自定义Serv…...

vue多行显示文字展开
这几天项目里面有一个需求,多行需要进行展开文字,类似实现这种效果 难点就在于页面布局 一开始就跟无头苍蝇似的,到处百度 ,后面发现网上的都不适合自己,最终想到了解决方案 下面是思路: 需求是超过3行&a…...

SpringBoot:SpringBoot 的底层运行原理解析
声明原文出处:狂神说 文章目录1. pom.xml1 . 父依赖2 . 启动器 spring-boot-starter2. 主启动类的注解1. 默认的主启动类2. SpringBootApplication3. ComponentScan4. SpringBootConfiguration5. SpringBootApplication 注解6. spring.factories7. 结论8. 简单图解3…...

哪些场景会产生OOM?怎么解决?
文章目录 堆内存溢出方法区(运行时常量池)和元空间溢出直接内存溢出栈内存溢出什么时候会抛出OutOfMemery异常呢?初看好像挺简单的,其实深究起来考察的是对整个JVM的了解,而这个问题从网上可以翻到一些乱七八糟的答案,其实在总结下来基本上4个场景可以概括下来。 堆内存溢出…...

金三银四、金九银十 面试宝典 Spring、MyBatis、SpringMVC面试题 超级无敌全的面试题汇总(超万字的面试题,让你的SSM框架无可挑剔)
Spring、MyBatis、SpringMVC 框架 - 面试宝典 又到了 金三银四、金九银十 的时候了,是时候收藏一波面试题了,面试题可以不学,但不能没有!🥁🥁🥁 一个合格的 计算机打工人 ,收藏夹里…...

JAVA开发(Spring框架详解)
javaweb项目几乎已经离不开spring框架了,spring 是一个典型的分层架构框架,它包含一系列的功能并被分为多个功能模块,springboot对spring框架又做了一层封装,以至于很多人对原来的spring框架越来越不了解。 要谈Spring的历史&…...

自学大数据第八天~HDFS命令(二)
嗨喽,好久不见,最近抽空复习了一下hadoop,书读百遍,其意自现这句话还真是; 继续学习HDFS常用命令 改变文件 拥有者~chown hdfs dfs -chown -R hadoop /user/hadoop使用 -R 将使改变在目录结构下递归进行。命令的使用者必须是超级用户。 改变文件所属组-chgrp hdfs dfs -chgr…...

贪心算法(几种常规样例)
贪心算法(几种常规样例) 贪心算法,指在对问题进行求解的时候,总是做出当前看来是最好的选择。也就是说不从整体上最优上考虑,算法得到的结果是某种意义上的局部最优解 文章目录贪心算法(几种常规样例&…...
Python|GIF 解析与构建(5):手搓截屏和帧率控制
目录 Python|GIF 解析与构建(5):手搓截屏和帧率控制 一、引言 二、技术实现:手搓截屏模块 2.1 核心原理 2.2 代码解析:ScreenshotData类 2.2.1 截图函数:capture_screen 三、技术实现&…...

大数据零基础学习day1之环境准备和大数据初步理解
学习大数据会使用到多台Linux服务器。 一、环境准备 1、VMware 基于VMware构建Linux虚拟机 是大数据从业者或者IT从业者的必备技能之一也是成本低廉的方案 所以VMware虚拟机方案是必须要学习的。 (1)设置网关 打开VMware虚拟机,点击编辑…...
macOS多出来了:Google云端硬盘、YouTube、表格、幻灯片、Gmail、Google文档等应用
文章目录 问题现象问题原因解决办法 问题现象 macOS启动台(Launchpad)多出来了:Google云端硬盘、YouTube、表格、幻灯片、Gmail、Google文档等应用。 问题原因 很明显,都是Google家的办公全家桶。这些应用并不是通过独立安装的…...
鸿蒙中用HarmonyOS SDK应用服务 HarmonyOS5开发一个医院查看报告小程序
一、开发环境准备 工具安装: 下载安装DevEco Studio 4.0(支持HarmonyOS 5)配置HarmonyOS SDK 5.0确保Node.js版本≥14 项目初始化: ohpm init harmony/hospital-report-app 二、核心功能模块实现 1. 报告列表…...

零基础设计模式——行为型模式 - 责任链模式
第四部分:行为型模式 - 责任链模式 (Chain of Responsibility Pattern) 欢迎来到行为型模式的学习!行为型模式关注对象之间的职责分配、算法封装和对象间的交互。我们将学习的第一个行为型模式是责任链模式。 核心思想:使多个对象都有机会处…...

并发编程 - go版
1.并发编程基础概念 进程和线程 A. 进程是程序在操作系统中的一次执行过程,系统进行资源分配和调度的一个独立单位。B. 线程是进程的一个执行实体,是CPU调度和分派的基本单位,它是比进程更小的能独立运行的基本单位。C.一个进程可以创建和撤销多个线程;同一个进程中…...
十九、【用户管理与权限 - 篇一】后端基础:用户列表与角色模型的初步构建
【用户管理与权限 - 篇一】后端基础:用户列表与角色模型的初步构建 前言准备工作第一部分:回顾 Django 内置的 `User` 模型第二部分:设计并创建 `Role` 和 `UserProfile` 模型第三部分:创建 Serializers第四部分:创建 ViewSets第五部分:注册 API 路由第六部分:后端初步测…...
Python竞赛环境搭建全攻略
Python环境搭建竞赛技术文章大纲 竞赛背景与意义 竞赛的目的与价值Python在竞赛中的应用场景环境搭建对竞赛效率的影响 竞赛环境需求分析 常见竞赛类型(算法、数据分析、机器学习等)不同竞赛对Python版本及库的要求硬件与操作系统的兼容性问题 Pyth…...

保姆级【快数学会Android端“动画“】+ 实现补间动画和逐帧动画!!!
目录 补间动画 1.创建资源文件夹 2.设置文件夹类型 3.创建.xml文件 4.样式设计 5.动画设置 6.动画的实现 内容拓展 7.在原基础上继续添加.xml文件 8.xml代码编写 (1)rotate_anim (2)scale_anim (3)translate_anim 9.MainActivity.java代码汇总 10.效果展示 逐帧…...

企业大模型服务合规指南:深度解析备案与登记制度
伴随AI技术的爆炸式发展,尤其是大模型(LLM)在各行各业的深度应用和整合,企业利用AI技术提升效率、创新服务的步伐不断加快。无论是像DeepSeek这样的前沿技术提供者,还是积极拥抱AI转型的传统企业,在面向公众…...