当前位置: 首页 > 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;几种常规样例&…...

Python|GIF 解析与构建(5):手搓截屏和帧率控制

目录 Python&#xff5c;GIF 解析与构建&#xff08;5&#xff09;&#xff1a;手搓截屏和帧率控制 一、引言 二、技术实现&#xff1a;手搓截屏模块 2.1 核心原理 2.2 代码解析&#xff1a;ScreenshotData类 2.2.1 截图函数&#xff1a;capture_screen 三、技术实现&…...

大数据零基础学习day1之环境准备和大数据初步理解

学习大数据会使用到多台Linux服务器。 一、环境准备 1、VMware 基于VMware构建Linux虚拟机 是大数据从业者或者IT从业者的必备技能之一也是成本低廉的方案 所以VMware虚拟机方案是必须要学习的。 &#xff08;1&#xff09;设置网关 打开VMware虚拟机&#xff0c;点击编辑…...

macOS多出来了:Google云端硬盘、YouTube、表格、幻灯片、Gmail、Google文档等应用

文章目录 问题现象问题原因解决办法 问题现象 macOS启动台&#xff08;Launchpad&#xff09;多出来了&#xff1a;Google云端硬盘、YouTube、表格、幻灯片、Gmail、Google文档等应用。 问题原因 很明显&#xff0c;都是Google家的办公全家桶。这些应用并不是通过独立安装的…...

鸿蒙中用HarmonyOS SDK应用服务 HarmonyOS5开发一个医院查看报告小程序

一、开发环境准备 ​​工具安装​​&#xff1a; 下载安装DevEco Studio 4.0&#xff08;支持HarmonyOS 5&#xff09;配置HarmonyOS SDK 5.0确保Node.js版本≥14 ​​项目初始化​​&#xff1a; ohpm init harmony/hospital-report-app 二、核心功能模块实现 1. 报告列表…...

零基础设计模式——行为型模式 - 责任链模式

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

并发编程 - go版

1.并发编程基础概念 进程和线程 A. 进程是程序在操作系统中的一次执行过程&#xff0c;系统进行资源分配和调度的一个独立单位。B. 线程是进程的一个执行实体,是CPU调度和分派的基本单位,它是比进程更小的能独立运行的基本单位。C.一个进程可以创建和撤销多个线程;同一个进程中…...

十九、【用户管理与权限 - 篇一】后端基础:用户列表与角色模型的初步构建

【用户管理与权限 - 篇一】后端基础:用户列表与角色模型的初步构建 前言准备工作第一部分:回顾 Django 内置的 `User` 模型第二部分:设计并创建 `Role` 和 `UserProfile` 模型第三部分:创建 Serializers第四部分:创建 ViewSets第五部分:注册 API 路由第六部分:后端初步测…...

Python竞赛环境搭建全攻略

Python环境搭建竞赛技术文章大纲 竞赛背景与意义 竞赛的目的与价值Python在竞赛中的应用场景环境搭建对竞赛效率的影响 竞赛环境需求分析 常见竞赛类型&#xff08;算法、数据分析、机器学习等&#xff09;不同竞赛对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技术的爆炸式发展&#xff0c;尤其是大模型&#xff08;LLM&#xff09;在各行各业的深度应用和整合&#xff0c;企业利用AI技术提升效率、创新服务的步伐不断加快。无论是像DeepSeek这样的前沿技术提供者&#xff0c;还是积极拥抱AI转型的传统企业&#xff0c;在面向公众…...