当前位置: 首页 > news >正文

并发编程---线程池(六)

阻塞队列的应⽤——线程池

  • 一 线程池基本概念
  • 二 线程池三种常⽤创建⽅式
    • 2.1.newFixedThreadPool线程池:
    • 2.2.newSingleThreadExecutor线程池:
    • 2.3.newCachedThreadPool线程池:
    • 2.4. 线程池代码演示
  • 三 线程池创建的七个参数
  • 四 线程池底层原理
    • 理解:
    • 案例图:
    • 原理图:
    • 流程图:
    • 线程池使用注意:
  • 五 线程池的拒绝策略
    • AbortPolicy拒绝策略
    • CallerRunsPolicy拒绝策略
    • DiscardOldestPolicy拒绝策略
    • DiscardPolicy拒绝策略
  • 六 实际⽣产使⽤哪⼀个线程池?
  • 七 ⾃定义线程池参数选择

一 线程池基本概念

概念: 线程池主要是控制运⾏线程的数量,将待处理任务放到等待队列,然后创建线程执⾏这些任务。 如果超过了最⼤线程数,则等待。
为什么⽤线程池?

10年前单核CPU电脑,假的多线程,像⻢戏团⼩丑玩多个球,CPU需要来回切换。
现在是多核电脑,多个线程各⾃跑在独⽴的CPU上,不⽤切换效率⾼。

线程池的优点:
线程池做的⼯作主要是控制运⾏的线程数量,处理过程中将任务放⼊队列,然后在线程创建后启动这些任务,如果线程数量超过了最⼤数量,超出数量的线程排队等候,等其他线程执⾏完毕,再从队列中取出任务来执⾏。
线程池的主要特点为:线程复⽤;控制最⼤并发数;管理线程。

  1. 线程复⽤:不⽤⼀直new新线程,重复利⽤已经创建的线程来降低线程的创建和销毁开销,节省系统资源。
  2. 提⾼响应速度:当任务达到时,不⽤创建新的线程,直接利⽤线程池的线程。
  3. 管理线程:可以控制最⼤并发数,控制线程的创建等。

体系: 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();}}
  1. newFixedThreadPool线程池
    创建线程数为5,观察结果发现5个线程一起执行
 //一个池子有5个工作线程,类似银行有5个受理窗口threadPoolTask(Executors.newFixedThreadPool(5));

在这里插入图片描述

  1. newSingleThreadExecutor线程池

创建newSingleThreadExecutor线程池,观察结果发现只有一个线程可以使用。

System.out.println("======Single Thread Pool=========");// //一个池子有1个工作线程,类似银行有1个受理窗口threadPoolTask( Executors.newSingleThreadExecutor() );

在这里插入图片描述

  1. newCachedThreadPool线程池:
    创建newCachedThreadPool,观察结果有10个客户,就有<=10个线程执行任务。有可能业务员办事快,接着又给其他客户办理业务
        System.out.println("=====Cached Thread Pool=======");// //不定量线程,一个池子有N个工作线程,类似银行有N个受理窗口threadPoolTask( Executors.newCachedThreadPool() );

在这里插入图片描述
问题:
上述我们使用10个客户来模拟,如果用100个呢,我们来观察结果
在这里插入图片描述

三 线程池创建的七个参数

在这里插入图片描述

参数意义
corePoolSize线程池中的常驻核⼼线程数
maximumPoolSize线程池中能够容纳同时并发的最⼤线程数,此值必须⼤于等于1
keepAliveTime多余的空闲线程的存活时间,当前池中线程数量超过corePoolSize时,当空闲时间达到keepAliveTime时,多余线程会被销毁直到只剩下corePoolSize个线程为⽌
unitkeepAliveTime存活时间的单位
workQueue任务队列,存放已提交但尚未执⾏的任务
threadFactory表示⽣成线程池中⼯作线程的线程⼯⼚,⽤于创建线程,⼀般默认的即可
handler拒绝策略,表示当队列满了,并且⼯作线程⼤于等于线程池的最⼤线程数(maximumPoolSize)时,如何来拒绝请求执⾏的runnable的策略

四 线程池底层原理

理解:

线程池的创建参数,就像⼀个银⾏。

  1. corePoolSize就像银⾏的“当值窗⼝“,⽐如今天有2位柜员在受理客户请求(任务)。
  2. 如果超过2个客户,那么新的客户就会在等候区(等待队列workQueue)等待。
  3. 当等候区也满了,这个时候就要开启“加班窗⼝”,让其它3位柜员来加班,此时达到最⼤窗⼝maximumPoolSize,为5个。
  4. 如果开启了所有窗⼝,等候区依然满员,此时就应该启动”拒绝策略handler ,告诉不断涌⼊的客户, 叫他们不要进⼊,已经爆满了。
  5. 由于不再涌⼊新客户,办完事的客户增多,窗⼝开始空闲,这个时候就通过 keepAlivetTime将多余的3个”加班窗⼝“取消,恢复到2个”当值窗⼝“

案例图:

在这里插入图片描述

原理图:

上⾯银⾏的例⼦,实际上就是线程池的⼯作原理。
在这里插入图片描述

流程图:

在这里插入图片描述
流程:

  1. 在创建了线程池后,开始等待请求。
  2. 当调⽤execute()⽅法添加⼀个请求任务时,线程池会做出如下判断:
    2.1 如果正在运⾏的线程数量⼩于corePoolSize,那么⻢上创建核⼼线程运⾏执⾏这个任务;
    2.2 如果正在运⾏的线程数量⼤于或等于corePoolSize,那么将这个任务放⼊队列;
    2.3 如果这个时候等待队列已满,且正在运⾏的线程数量⼩于maximumPoolSize ,那么还是要创
    建⾮核⼼线程⽴刻运⾏这个任务;
    2.4 如果这个时候等待队列已满,且正在运⾏的线程数量⼤于或等于 maximumPoolSize,那么线程池会启动饱和拒绝策略来执⾏。
  3. 当⼀个线程完成任务时,它会从等待队列中取出下⼀个任务来执⾏。
  4. 当⼀个线程⽆事可做超过⼀定的时间( keepAliveTime)后,线程会判断:
    如果当前运⾏的线程数⼤于 corePoolSize,那么这个⾮核⼼线程就被停掉。当线程池的所有任
    务完成后,它最终会收缩到corePoolSize的⼤⼩。

线程池使用注意:

《Java 开发⼿册》是阿⾥巴巴集团技术团队:

在这里插入图片描述

五 线程池的拒绝策略

在这里插入图片描述
当等待队列满时,且达到最⼤线程数,再有新任务到来,就需要启动拒绝策略。JDK提供了四种拒绝策
略,分别是:

  1. AbortPolicy:默认的策略,直接抛出 RejectedExecutionException异常,阻⽌系统正常运⾏。
  2. CallerRunsPolicy:既不会抛出异常,也不会终⽌任务,⽽是将任务返回给调⽤者,从⽽降低新任务的流量。
  3. DiscardOldestPolicy:抛弃队列中等待最久的任务,然后把当前任务加⼊队列中尝试再次提交任务。
  4. DiscardPolicy:该策略默默地丢弃⽆法处理的任务,不予任何处理也不抛出异常。如果允许任务丢失,这是最好的⼀种策略。

AbortPolicy拒绝策略

在这里插入图片描述

CallerRunsPolicy拒绝策略

在这里插入图片描述

DiscardOldestPolicy拒绝策略

在这里插入图片描述

DiscardPolicy拒绝策略

在这里插入图片描述

六 实际⽣产使⽤哪⼀个线程池?

单⼀、可变、定⻓都不⽤!原因就是FixedThreadPoolSingleThreadExecutor底层都是⽤ 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线程池&#xff1a;2.2.newSingleThreadExecutor线程池&#xff1a;2.3.newCachedThreadPool线程池&#xff1a;2.4. 线程池代码演示三 线程池创建的七个参数四 线程池底层原理理解&…...

【Java实战】不会还有人用if else进行参数校验吧

当请求参数很多&#xff0c;几乎每一个参数都需要后端去兜底校验时&#xff0c;你还在写if else去判断参数是否为空吗&#xff1f;&#xff1f;要校验为空的参数三四个还好&#xff0c;要是十几个&#xff0c;业务逻辑还没开始就写二三十行代码开始堆山了嘛&#xff0c;教给大家…...

深度学习部署(十六): CUDA RunTime API _vector-add 使用cuda核函数实现向量加法

1. 知识点 nthreads的取值&#xff0c;不能大于block能取值的最大值。一般可以直接给512、256&#xff0c;性能就是比较不错的 (input_size block_size - 1) / block_size;是向上取整 对于一维数组时&#xff0c;采用只定义layout的x维度&#xff0c;若处理的是二维&#xff…...

堆结构的两个应用

堆排序 堆结构很大的一个用处&#xff0c;就是用于堆排序了&#xff0c;堆排序的时间复杂度是O(n∗log2n)O(n*log_2n)O(n∗log2​n)量级的&#xff0c;在众多排序算法中所处的地位也是高手级别的了。 但很多人在使用堆排序的时候&#xff0c;首先认为我必须得有一个堆数据结构…...

Java中的 static

1 static 静态变量 1.1 静态变量的使用 static变量也称作静态变量&#xff0c;也叫做类变量 静态变量被所有的对象所共享&#xff0c;在内存中只有一个副本 当且仅当在类初次加载时会被初始化 静态变量属于类 通过类名就可以直接调用静态变量 也可以通过对象名.静态变量…...

基于Vision Transformer的图像去雾算法研究与实现(附源码)

基于Vision Transformer的图像去雾算法研究与实现 0. 服务器性能简单监控 \LOG_USE_CPU_MEMORY\文件夹下的use_memory.py文件可以实时输出CPU使用率以及内存使用率&#xff0c;配合nvidia-smi监控GPU使用率 可以了解服务器性能是否足够&#xff1b;运行时在哪一步使用率突然…...

服务器相关常用的命令

cshell语法 https://www.doc88.com/p-4985161471426.html domainname命令 1&#xff09;查看当前系统域名 domainname2&#xff09;设置并查看当前系统域名 domainname example.com3&#xff09;显示主机ip地址 domainname -Iwhich命令 which 系统命令在 PATH 变量指定的…...

今天是国际数学日,既是爱因斯坦的生日又是霍金的忌日

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

Qt Quick - StackLayout 堆布局

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

C/C++网络编程笔记Socket

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

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多行显示文字展开

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

SpringBoot:SpringBoot 的底层运行原理解析

声明原文出处&#xff1a;狂神说 文章目录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 框架 - 面试宝典 又到了 金三银四、金九银十 的时候了&#xff0c;是时候收藏一波面试题了&#xff0c;面试题可以不学&#xff0c;但不能没有&#xff01;&#x1f941;&#x1f941;&#x1f941; 一个合格的 计算机打工人 &#xff0c;收藏夹里…...

JAVA开发(Spring框架详解)

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

自学大数据第八天~HDFS命令(二)

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

贪心算法(几种常规样例)

贪心算法&#xff08;几种常规样例&#xff09; 贪心算法&#xff0c;指在对问题进行求解的时候&#xff0c;总是做出当前看来是最好的选择。也就是说不从整体上最优上考虑&#xff0c;算法得到的结果是某种意义上的局部最优解 文章目录贪心算法&#xff08;几种常规样例&…...

C# 求圆面积的程序(Program to find area of a circle)

给定半径r&#xff0c;求圆的面积。圆的面积应精确到小数点后5位。 例子&#xff1a; 输入&#xff1a;r 5 输出&#xff1a;78.53982 解释&#xff1a;由于面积 PI * r * r 3.14159265358979323846 * 5 * 5 78.53982&#xff0c;因为我们只保留小数点后 5 位数字。 输…...

【数据分析】R版IntelliGenes用于生物标志物发现的可解释机器学习

禁止商业或二改转载&#xff0c;仅供自学使用&#xff0c;侵权必究&#xff0c;如需截取部分内容请后台联系作者! 文章目录 介绍流程步骤1. 输入数据2. 特征选择3. 模型训练4. I-Genes 评分计算5. 输出结果 IntelliGenesR 安装包1. 特征选择2. 模型训练和评估3. I-Genes 评分计…...

Kafka入门-生产者

生产者 生产者发送流程&#xff1a; 延迟时间为0ms时&#xff0c;也就意味着每当有数据就会直接发送 异步发送API 异步发送和同步发送的不同在于&#xff1a;异步发送不需要等待结果&#xff0c;同步发送必须等待结果才能进行下一步发送。 普通异步发送 首先导入所需的k…...

tomcat入门

1 tomcat 是什么 apache开发的web服务器可以为java web程序提供运行环境tomcat是一款高效&#xff0c;稳定&#xff0c;易于使用的web服务器tomcathttp服务器Servlet服务器 2 tomcat 目录介绍 -bin #存放tomcat的脚本 -conf #存放tomcat的配置文件 ---catalina.policy #to…...

如何配置一个sql server使得其它用户可以通过excel odbc获取数据

要让其他用户通过 Excel 使用 ODBC 连接到 SQL Server 获取数据&#xff0c;你需要完成以下配置步骤&#xff1a; ✅ 一、在 SQL Server 端配置&#xff08;服务器设置&#xff09; 1. 启用 TCP/IP 协议 打开 “SQL Server 配置管理器”。导航到&#xff1a;SQL Server 网络配…...

echarts使用graphic强行给图增加一个边框(边框根据自己的图形大小设置)- 适用于无法使用dom的样式

pdf-lib https://blog.csdn.net/Shi_haoliu/article/details/148157624?spm1001.2014.3001.5501 为了完成在pdf中导出echarts图&#xff0c;如果边框加在dom上面&#xff0c;pdf-lib导出svg的时候并不会导出边框&#xff0c;所以只能在echarts图上面加边框 grid的边框是在图里…...

6.9本日总结

一、英语 复习默写list11list18&#xff0c;订正07年第3篇阅读 二、数学 学习线代第一讲&#xff0c;写15讲课后题 三、408 学习计组第二章&#xff0c;写计组习题 四、总结 明天结束线代第一章和计组第二章 五、明日计划 英语&#xff1a;复习l默写sit12list17&#…...

以太网PHY布局布线指南

1. 简介 对于以太网布局布线遵循以下准则很重要&#xff0c;因为这将有助于减少信号发射&#xff0c;最大程度地减少噪声&#xff0c;确保器件作用&#xff0c;最大程度地减少泄漏并提高信号质量。 2. PHY设计准则 2.1 DRC错误检查 首先检查DRC规则是否设置正确&#xff0c;然…...

[10-1]I2C通信协议 江协科技学习笔记(17个知识点)

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17...

Xcode 16.2 版本 pod init 报错

Xcode 版本升级到 16.2 后&#xff0c;项目执行 pod init 报错&#xff1b; ### Error RuntimeError - PBXGroup attempted to initialize an object with unknown ISA PBXFileSystemSynchronizedRootGroup from attributes: {"isa">"PBXFileSystemSynchron…...