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

JavaEE:线程池精讲

目录

一.什么是线程池

二.线程池的实现原理

🎈为什么要有工厂模式?

三.线程池的构造方法解读

🎈线程池的拒绝策略

四.自己实现一个线程池


一.什么是线程池

简单来说,线程池就好比一块鱼塘,鱼塘中的每条鱼就是一个线程。那么为什么要有这个线程池呢?就好比 一个“渣女\渣男”,当他和A在一起的时候,如果想和B在一起,那么就需要先想办法和A分手,再和B搞好关系,最终和B在一起。如果她和A谈的时候,已经找好了B C D,此时就可以直接拿来无缝衔接~~

其实线程池也就大概这个作用,里面存放一些线程,需要用的时候直接拿来使用。

二.线程池的实现原理

我们先来看线程池是如何创建的:

package Pool;import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;public class threadPoolDemo {public static void main(String[] args) {ExecutorService executor = Executors.newSingleThreadExecutor();}
}

很明显,此处的线程池竟然不是 new 出来的,那么它是如何被实例化的呢?其实这里就使用了一种设计模式:工厂模式。

🎈为什么要有工厂模式?

其实工厂模式就时给Java中的构造方法填坑的,我们的构造方法其实时有很大缺陷的,我们来看以下例子。

我们期望这个Point类,初始化的时候能够传入 double x,double y,用来构造笛卡尔坐标系

我们又希望在不创建其他类的情况下,这个Point类, 初始化的时候能够传入 double r,double a,用来构造极坐标系。

但是构造方法也是方法,此时的方法由于参数个数和参数的类型都相同,就会编译失败,那么就没办法满足期望!

此时我们可以再写一个类:

此时这个类中又两个静态方法,一个是构造笛卡尔坐标系,并且返回。一个是构造及坐标系,并且返回对象。

那么我们就可以使用以下语句来分别调用:

Point p1 = PointFactory.makePintByXY(10,20) 

Point p2 = PointFactory.makePintByRA(12,63) 

此时通过PointFactory类,来给Point类传入需要的值就可以了。


那么线程池也是通过这样的方式来进行创建的:

三.线程池的构造方法解读

从Excutor这个工厂类的源码中可以得到以下:

其实线程的创建又被封装到了一个叫做ThreadPoolExecutor的类中

点开ThreadPoolExecutor,可以得到如下图片:

其中的每个参数的意思是这样的:

第一个是核心线程数, 第二个是最大线程数

线程池中的线程数目是可以动态变化的

范围就是【int corPoolSize. ~ int maxmumPoolSize】

什么是核心线程:

就好比一个公司中有正式员工(核心线程)和实习生,总的员工数目不能超过一定的值。当人手不够用就招实习生,这样既可以满足效率的需求,又可以避免过多的开销。

第三个是线程的可存活时间

第四个TimeUnit unit是用来设置非核心线程闲置超时时长(keepAliveTime)的单位。当一个非核心线程的闲置时间超过这个参数所设定的时长时,该线程就会被销毁掉。

第五个比较重要

第六个是线程池的拒绝策略,也就是当所有线程都处于忙碌状态,如果还往线程池中添加元素,线程池所做的操作。

这些构造方法,第一个和第五个以及第六个是需要重点掌握的。 

下面来单独讲讲第六个参数:拒绝策略

🎈线程池的拒绝策略

所谓的拒绝策略,其实就是如果线程池中每个线程都是处于忙碌的状态,如何应对新来的线程任务。

举个例子:如果我周一到周五都是满课,此时我一朋友让我给他去代课,那么此时我如何应对?此时就会有相应的应对策略:

  1. AbortPolicy(默认策略):这是默认的拒绝策略,它会抛出一个未检查的RejectedExecutionException,以指示任务被拒绝。也就是我本来都满课了,朋友还让我去代课,此时我就直接崩溃,代课和我自己的课我都不去上了,直接崩溃!
  2. CallerRunsPolicy:这个策略不会抛出异常。相反,它会将任务退回给调用线程,让它自己运行这个任务。 也就是让我朋友自己去上课。
  3. DiscardOldestPolicy:此策略会丢弃队列中等待最久的任务,并立即返回给调用者。也就是我丢弃我课程中一节课,去给他代课。
  4. DiscardPolicy:这个策略会静默地丢弃被拒绝的任务。也就是说,它不会抛出任何异常,也不会通知任务被拒绝。 也就是我拒绝去给他代课,我自己上自己的课。然后我朋友也不去上课了,那么这个课(任务) 也就黄了。

四.自己实现一个线程池

  实现线程池一个最关键的步骤就是拒绝策略,那么说明拒绝策略呢?

由于之前学过阻塞队列的知识,这里就先用阻塞队列来实现以下。

那么这个就是一种自己定义的新的拒绝策略,那就是一直等待~

package Pool;import java.util.concurrent.ArrayBlockingQueue;
import java.util.concurrent.BlockingQueue;class MyPoolDemo {//一个队列BlockingQueue<Runnable> queue = new ArrayBlockingQueue<>(1000);//通过这个方法,把任务添加到队列当中public void submit(Runnable task) throws InterruptedException {queue.put(task); //往阻塞队列中放入元素}public MyPoolDemo(int n) throws InterruptedException {//构造方法for (int i = 0; i < n; i++) {Thread t = new Thread(() -> {//让这个线程从队列中消费任务并且进行执行try {//如果队列中没有元素,那就阻塞等待//一旦队列中有了任务,那么就立即执行take方法获取到任务并且开始执行Runnable task = task = queue.take();task.run();} catch (InterruptedException e) {throw new RuntimeException(e);}});t.start();}}}
public class RunDemo {public static void main(String[] args) throws InterruptedException {/*** 步骤理解:* 1.创建线程池并且指定线程数目是 20 ,在实例化线程池的时候已经创建好了20个线程* 2.这20个线程都在等待 take 获取到任务队列中的任务* 3.for 语句 循环 1000次,每次循环都会提交任务到任务队列* 4.一但任务队列里面有元素,这20个线程就会立马获取到,并且执行*/MyPoolDemo myPoolDemo = new MyPoolDemo(20);int taskCount = 1000;while (true) {for (int i = 0; i < taskCount; i++) {int id = i;myPoolDemo.submit(new Runnable() {@Overridepublic void run() {System.out.println("执行任务:" + id);}});}}}}

运行结果:

代码解读:

1.线程池里的线程是需要执行任务的,这个任务可以放到    BlockingQueue 这个阻塞队列中。为什么要使用阻塞队列呢?当线程池中的线程都在工作,此时就直接等待阻塞。

2.submit 方法接受一个实例化好的Runnable类型的任务,负责往队列中添加元素

3. MyPoolDemo(int n) 是这个类的构造放法,当实例化这个类的时候,被指定的 n 就是要创建的线程数量。

4. 由运行结果可以得出:当线程数量为20的时候,可以看到任务被随即执行完了。


总结:Java线程池是Java并发编程中一个重要的概念,它用于管理和控制线程的创建、销毁,以及任务提交和执行。线程池的主要目的是减少创建和销毁线程的开销,提高性能。 

相关文章:

JavaEE:线程池精讲

目录 一.什么是线程池 二.线程池的实现原理 &#x1f388;为什么要有工厂模式&#xff1f; 三.线程池的构造方法解读 &#x1f388;线程池的拒绝策略 四.自己实现一个线程池 一.什么是线程池 简单来说&#xff0c;线程池就好比一块鱼塘&#xff0c;鱼塘中的每条鱼就是一个线程…...

spring-cloud-starter-gateway-mvc的网关实现

一 概括 最近&#xff0c;我也一直在使用SpringCloudGateway开发我们自己的网关产品。根据我对官网文档&#xff1a;https://docs.spring.io/spring-cloud-gateway/reference/spring-cloud-gateway-server-mvc.html 的理解&#xff0c;内容如下&#xff1a; SpringCloudGatew…...

《PySpark大数据分析实战》-11.Spark on YARN模式安装Hadoop

&#x1f4cb; 博主简介 &#x1f496; 作者简介&#xff1a;大家好&#xff0c;我是wux_labs。&#x1f61c; 热衷于各种主流技术&#xff0c;热爱数据科学、机器学习、云计算、人工智能。 通过了TiDB数据库专员&#xff08;PCTA&#xff09;、TiDB数据库专家&#xff08;PCTP…...

多架构容器镜像构建实战

最近在一个国产化项目中遇到了这样一个场景&#xff0c;在同一个 Kubernetes 集群中的节点是混合架构的&#xff0c;也就是说&#xff0c;其中某些节点的 CPU 架构是 x86 的&#xff0c;而另一些节点是 ARM 的。为了让我们的镜像在这样的环境下运行&#xff0c;一种最简单的做法…...

通过层进行高效学习:探索深度神经网络中的层次稀疏表示

一、介绍 深度学习中的层次稀疏表示是人工智能领域日益重要的研究领域。本文将探讨分层稀疏表示的概念、它们在深度学习中的意义、应用、挑战和未来方向。 最大限度地提高人工智能的效率和性能&#xff1a;深度学习系统中分层稀疏表示的力量。 二、理解层次稀疏表示 分层稀疏表…...

自然语言处理阅读第二弹

HuggingFace 镜像网站模型库 HuggingFace中bert实现 下游任务介绍重要源码解读 NLP中的自回归模型和自编码模型 自回归&#xff1a;根据上文内容预测下一个可能的单词&#xff0c;或者根据下文预测上一个可能的单词。只能利用上文或者下文的信息&#xff0c;不能同时利用上…...

利用canvas封装录像时间轴拖动(uniapp),封装上传uniapp插件市场

gitee项目地址,项目是一个空项目,其中包含了封装的插件,自己阅读,由于利用了canvas所以在使用中暂不支持.nvue,待优化; 项目也是借鉴了github上的一个项目,timeline-canvas,​​​​​​​ ​​​​​​​...

PDF转为图片

PDF转为图片 背景pdf展示目标效果 发展过程最终解决方案&#xff1a;python PDF转图片pdf2image注意&#xff1a;poppler 安装 背景 最近接了一项目&#xff0c;主要的需求就是本地的文联单位&#xff0c;需要做一个电子刊物阅览的网站&#xff0c;将民族的刊物发布到网站上供…...

隐私计算介绍

这里只对隐私计算做一些概念性的浅显介绍&#xff0c;作为入门了解即可 目录 隐私计算概述隐私计算概念隐私计算背景国外各个国家和地区纷纷出台了围绕数据使用和保护的公共政策国内近年来也出台了数据安全、隐私和使用相关的政策法规 隐私计算技术发展 隐私计算技术安全多方计…...

HTML有哪些列表以及具体的使用!!!

文章目录 一、HTML列表二、列表的应用1、无序列表2、有序列表3、自定义列表 三、总结 一、HTML列表 html的列表有三种&#xff0c;一种是无序列表&#xff0c;一种是有序列表&#xff0c;还有一种为自定义列表。 二、列表的应用 1、无序列表 <ul> <li>无序列表…...

DriveWorks Solo捕获参数(二)

捕获参数-帧 顶门框 现在让我们捕获框架。它由2部分组成&#xff1b;两者都有一个需要捕捉的维度。 1.通过单击“捕获资源管理器”中的标题来激活“捕获的模型”部分。 2.展开框架组件。 3.双击任务窗格树中的模型顶门侧柱。 这将在SOLIDWORKS中打开模型顶门门框&#xff0c;并…...

基于开源的JAVA mongodb jdbc 驱动 使用教程

基于开源的JAVA mongodb jdbc 驱动 使用教程介绍 介绍 本文介绍一款开源的基于JAVA的 Mongodb JDBC 驱动使用教程 开源地址 https://gitee.com/bgong/jdbc-mongodb-driver功能价值 与mybaits融合&#xff1a;复用mybatis的功能特性&#xff0c;如:缓存,if动态判断标签等特…...

[RK-Linux] RK3399使用RK开源SPL,修改U-Boot为FIT打包方式,裁剪trust分区

文章目录 一、启动方式二、FIT打包三、RK3568相关配置参考四、RK3399支持与调试一、启动方式 RK3399平台根据前级Loader代码是否开源,目前有两套启动方式: // 前级loader闭源 BOOTROM => ddr bin => Miniloader => TRUST => U-BOOT => KERNEL // 前级loader…...

【网络安全】-Linux操作系统—VMWare软件

文章目录 VMWare软件的安装选择VMWare版本下载VMWare安装过程 VMWare的常用操作创建新的虚拟机配置虚拟机启动和关闭虚拟机安装VMWare Tools VMWare的克隆和快照克隆&#xff08;Clone&#xff09;快照&#xff08;Snapshot&#xff09; 总结 VMWare是一种流行的虚拟化软件&…...

关于chatgpt一点肤浅认识

001 词向量 用数字向量表示单词。它是计算机更好地理解单词 1、预训练 – 就是先训练一个模型&#xff0c;用于以后特定任务的微调&#xff0c;比如将 BERT这个模型用于特定的NLP任务&#xff0c;比如情感分析 2、one-hot: 用只有一个元素是1&#xff0c;其他是0的向量表示物体…...

Redis结合SpringBoot 基本使用

1.1 简介 1.1.1 概述 Spring Data 中有一个成员 Spring Data Redis&#xff0c;他提供了 RedisTemplate 可以在 Spring 应用中更简便的访问 Redis 以及异常处理及序列化&#xff0c;支持发布订阅等操作。 1.2 RedisTemplate 常见 API   RedisTemplate 针对 jedis 客户端中大…...

JAVA主流日志框架梳理学习及使用

前言&#xff1a;目前市面上有挺多JAVA的日志框架&#xff0c;比如JUL(JDK自带的日志框架),Log4j,Logback,Log4j2等&#xff0c;有人可能有疑问说还有slf4j&#xff0c;不过slf4j不是一种日志框架的具体实现&#xff0c;而是一种日志门面&#xff08;日志门面可以理解为是一种统…...

java多个设计模式解决大量if-else堆积

当面对大量的 if-else 语句时&#xff0c;可以考虑使用以下几种常见的设计模式来减少代码的复杂性和维护成本&#xff1a; 策略模式&#xff08;Strategy Pattern&#xff09;&#xff1a;将各个分支的逻辑封装成不同的策略类&#xff0c;然后通过一个上下文类来根据条件选择合…...

js DOM的一些小操作 获取节点集合Node( getElementsByClassName等)

1. getElementsByClassName(names) 返回文档中所有含有指定类名的节点 document.getElementsByClassName(a) 返回所有类名为a的节点 2.getElementsByName(name) 返回文档中所有指定name的节点。 标签可以有name属性。 3. querySelectorAll(selectors) 返回文档中所有匹配…...

Arcgis导出为tiff

原有一幅影像&#xff0c;在进行一些操作之后&#xff0c;需要导出为tiff 比如我对他进行一个重采样&#xff0c;48m分辨率变为96m 在重采样后的数据图层上右键&#xff0c;导出数据 为什么有时会导出为.gdb格式的呢&#xff1f; 可能是位置处在一个文件地理数据库.gdb下...

nginx中的root and alias命令的区别

Ubuntu关于Nginx的命令&#xff1a; 1、安装Nginx&#xff1a; apt-get install nginx2、查看Nginx运行状态&#xff1a; systemctl status nginx3、启动Nginx&#xff1a; systemctl start nginx4、停止Nginx&#xff1a; systemctl stop nginx5、重启Nginx&#xff1a; …...

python提取图片型pdf中的文字(提取pdf扫描件文字)

前言 文字型pdf提取&#xff0c;python的库一大堆&#xff0c;但是图片型pdf和pdf扫描件提取&#xff0c;还是有些难度的&#xff0c;我们需要用到OCR&#xff08;光学字符识别&#xff09;功能。 一、准备 1、安装OCR&#xff08;光学字符识别&#xff09;支持库 首先要安…...

08‐Mysql全局优化与Mysql 8.0新特详解

文章目录 Mysql全局优化总结配置文件my.ini或my.cnf的全局参数最大连接数允许用户连接的最大数量MySQL能够暂存的连接数量JDBC连接空闲等待时长client连接空闲等待时长innodb线程并发数innodb存储引擎buffer pool缓存大小行锁锁定时间redo log写入策略binlog写入磁盘机制排序线…...

【LeetCode刷题笔记】155.最小栈

创作不易&#xff0c;本篇文章如果帮助到了你&#xff0c;还请点赞 关注支持一下♡>&#x16966;<)!! 主页专栏有更多知识&#xff0c;如有疑问欢迎大家指正讨论&#xff0c;共同进步&#xff01; 更多算法知识专栏&#xff1a;算法分析&#x1f525; 给大家跳段街舞感谢…...

我的4096创作纪念日

机缘 岁月如梭&#xff0c;时光一晃已经在CSDN扎根4096天了。第一次注册CSDN好像还是在2012年&#xff0c;那会还没大学毕业。初入CSDN&#xff0c;只是把他当作自己编程时遇到问题的在线笔记记录而已&#xff0c;没想到无意间还帮助了其他遇到同样问题困扰的同学。而在这4096…...

Java Web 01_HTML4HTML5基础标签语法

HMTL基础 1.什么是HTML Hyper Text Markup Language (超文本标记语言)标记又俗称标签(tag)&#xff0c;一般格式&#xff1a; <tagName></tagName> 如 <h1></h1>标签里还可以有属性(Attribute)&#xff1a; <tagName Atrribute “value” />…...

Androidstudio加载编译时kotlin-compiler-embeddable一直下载中

打开网址 https://repo.maven.apache.org/maven2/org/jetbrains/kotlin/kotlin-compiler-embeddable/1.6.10/ 1.下载jar包 2.配置下载jar文件到.gradle文件中 文件路径:/Users/“用户名”/.gradle/caches/modules-2/files-2.1/org.jetbrains.kotlin/kotlin-compiler-embedd…...

案例073:基于微信小程序的智慧旅游平台开发

文末获取源码 开发语言&#xff1a;Java 框架&#xff1a;SSM JDK版本&#xff1a;JDK1.8 数据库&#xff1a;mysql 5.7 开发软件&#xff1a;eclipse/myeclipse/idea Maven包&#xff1a;Maven3.5.4 小程序框架&#xff1a;uniapp 小程序开发软件&#xff1a;HBuilder X 小程序…...

Flink系列之:Flink 1.8.0 中的状态 TTL:如何在 Apache Flink 中自动清理应用程序状态

Flink系列之&#xff1a;Flink 1.8.0 中的状态 TTL&#xff1a;如何在 Apache Flink 中自动清理应用程序状态 一、状态的瞬态性质二、用于持续清理应用程序状态的状态 TTL三、倒垃圾四、保持完整状态快照干净五、堆状态后端的增量清理六、RocksDB 后台压缩以过滤掉过期状态七、…...

2023 亚马逊云科技 re:Invent 大会探秘:Aurora 无限数据库的突破性应用

文章目录 一、前言二、Amazon Aurora 无限数据库2.1 亚马逊云科技数据库产品发展历程2.2 什么是 Amazon Aurora Limitless Database&#xff08;无限数据库&#xff09;2.3 Amazon Aurora Limitless Database 设计架构2.4 Amazon Aurora Limitless Database 分片功能2.5 使用 A…...