线程池是啥有啥用,怎么用,如何自己实现一个

目录

一、线程池是啥,有啥用

二、线程池怎么用 

1.构造方法 

2.如何使用Java的线程池  

三、简单实现一个线程池


假设我是一个(好看+有才华) 的妹子,那么我就会有很多追求者,这些也叫备胎们,我们若把他们放到一个地方,那就叫“备胎池”。同理,线程就叫“线程池”。

一、线程池是啥,有啥用

频繁的创建销毁线程开销太大,所以我们会先创建一些线程放着,要用的时候直接拿就行了,这些线程都放一块地方,用完之后再放回这个地方,那么我们管这个地方叫“线程池”。

 所以:线程池最⼤的好处就是减少每次启动、销毁线程的损耗。

 

那么为什么线程池的效率更高,开销更小呢? 

 那么就得谈谈:用户态和内核态

比如说:

1)在银行你要办业务,可能会需要身份证或者户口本复印件,这时候,你如果没带,那么银行可能会有复印机。

2)那么你有2种选择:第一种是去柜台让柜员帮你,第二种是自己去大厅的复印机复印。

3)内核态:如果让柜员帮你去后台复印,可能没这么快,柜员也许要帮别人也复印,也可能去摸鱼,也可能去上个厕所。我们知道操作系统是由内核和软件组成,有很多软件都需要内核管理,可能会没那么及时。

4)用户态:如果你是自己去大厅复印,自给自足,非常的快。

5)而我们的线程池就是用户态,自己创建线程是内核态,所以效率会比线程池低。

二、线程池怎么用 

 我们有专门的类表示线程池:ThreadPoolExecutor

1.构造方法 

下面是它的构造方法,最主要的是第4个最为全面,其他三个都是从第4个演化出来的。

 我们分析一下这个线程池的参数:

  • corePoolSize:正式员⼯的数量. (正式员⼯, ⼀旦录⽤, 永不辞退)
  • maximumPoolSize: 正式员⼯ + 临时⼯的数⽬. (临时⼯: ⼀段时间不⼲活, 就被辞退)
  • keepAliveTime: 临时⼯允许的空闲时间
  • unit: keepaliveTime 的时间单位, 是秒, 分钟, 还是其他值
  • workQueue: 传递任务的阻塞队列
  • threadFactory: 创建线程的⼯⼚, 参与具体的创建线程⼯作,通过不同线程⼯⼚创建出的线程相当于 对⼀些属性进⾏了不同的初始化设置
  • RejectedExecutionHandler: 拒绝策略, 如果任务量超出公司的负荷了接下来怎么处理 
    1. AbortPolicy(): 超过负荷, 直接抛出异常          
    2. CallerRunsPolicy(): 调⽤者负责处理多出来的任务     
    3. DiscardOldestPolicy(): 丢弃队列中最⽼的任务
    4. DiscardPolicy(): 丢弃新来的任务  

1)corePoolSize和maximumPoolSize中,如果核心线程数是M个,在使用的过程中发现不够用,会自动扩容多M个,直至最大线程数max个。

 2)keepAliveTime和unit是姐妹,一起用的,就是实习生(非核心线程)太久没活干了,就会裁掉它,怎么样才算太久呢?就需要你自己设置一个时间

3)workQueue是我们需要传进去的堵塞队列,线程池就是一个生产者消费者模型,程序员把任务submit放进线程池中。这个队列可以自己设计容量和类型。

4)线程工厂,是为了弥补构造方法的不足,比如假设我在二维中需要表示一个点,我有2种方法,第一种是横纵坐标,第二种是用极坐标,

但是这样的话重载就失效了,因为名字参数什么的啥都一样啊,构成不了重载。

而是需要工厂设计模式解决,如上图。

5)拒绝策略(重点):当线程池的要执行的任务满了,它就会进行堵塞。但是有时候这未必是件好事。比如说你女神直接拒绝你,比起干耗着你好,这样你就能开启新的生活了。

假设线程池是女神,你是任务,但是备胎太多了忙不过来。

第一个就是女神拒绝了你,你崩溃了,其他备胎也崩溃了(没想到女神有这么多备胎);

第二个女神不想你追她,让你去追其他小姐姐,但是女神依旧和备胎们约会;

第三个是把追的最久的备胎扔掉,没新鲜感了,和最新追我的约会;

第四个是把最新的备胎踢掉,是个念旧的女神,就当一切没有发生,继续和之前的备胎们约会。

2.如何使用Java的线程池  

虽然ThreadPoolExecutor固然强大,但是参数太多,用起来确实麻烦,所以Java标准库中有更方便的:Executor提供了一些工厂方法,比如:

接受线程池的类型:ExecutorService

创建便捷线程池的方法:newFixedThreadPool(),把核心线程数和最大线程数设置成一样,不会自动扩容

添加任务到线程池执行:submit() 

public static void main(String[] args) throws InterruptedException {ExecutorService service=Executors.newFixedThreadPool(4);for(int i=0;i<100;i++){int id=i;service.submit(()->{Thread current=Thread.currentThread();System.out.println("hello world "+id+ " "+current.getName());});}Thread.sleep(2000);service.shutdown();System.out.println("程序结束");}

三、简单实现一个线程池

需要如下条件:

一个堵塞队列queue,来装要执行的任务,通过take取任务。

线程池类,来用for循环放线程(相当于线程池),这个类有submit()方法用queue队列中用put就能放进去执行这些线程中。

(由于拒绝策略太麻烦了,这里没有写出来,感兴趣的可以自行写一下)

class MyThreadPool {private BlockingQueue<Runnable> queue = new ArrayBlockingQueue<>(1000);//创造线程public MyThreadPool(int n) {for (int i = 0; i < n; i++) {Thread t = new Thread(() -> {while (true) {try {Runnable runnable=queue.take();runnable.run();} catch (InterruptedException e) {e.printStackTrace();}}});t.start();}}//创建任务public void submit(Runnable runnable) throws InterruptedException {queue.put(runnable);}
}public class demo15 {public static void main(String[] args) throws InterruptedException {MyThreadPool myThreadPool=new MyThreadPool(4);for(int i=0;i<1000;i++){int id=i;myThreadPool.submit(()->{System.out.println("执行任务 "+id+" "+Thread.currentThread().getName());});}}}
  •  核⼼操作为 submit,将任务加⼊线程池中
  •  使⽤ Worker 类描述⼀个⼯作线程。使⽤ Runnable 描述⼀个任务.
  •  使⽤⼀个 BlockingQueue 组织所有的任务
  •  每个 worker 线程要做的事情:不停的从 BlockingQueue 中取任务并执⾏
  •  指定⼀下线程池中的最⼤线程数 maxWorkerCount;当当前线程数超过这个最⼤值时,就不再新增线程了

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.xdnf.cn/news/142435.html

如若内容造成侵权/违法违规/事实不符,请联系一条长河网进行投诉反馈,一经查实,立即删除!

相关文章

应用性能优化实践(一)ArkTS高性能编程

在开发HarmonyOS应用时&#xff0c;优化应用性能是至关重要的。通过ArkTS高性能编程、减少丢帧卡顿、提升应用启动和响应速度&#xff0c;可以有效提升用户体验。 一、ArkTS高性能编程 ArkTS是基于TypeScript涉及的&#xff0c;但出于编码的稳定性和性能考虑&#xff0c;一些T…

QT项目添加资源文件

效果 1.先将图片等资源文件复制到QT项目源码目录中。 2.再添加资源文件 打开资源文件编辑 全选文件 代码

【遥感图像船舶检测数据集】

【遥感图像船舶检测数据集】nc1 标签names: [ship,] 名称&#xff1a;【‘船’】共4126张&#xff0c;8:1:1比例划分&#xff0c;&#xff08;train;3300张&#xff0c;val&#xff1a;412张&#xff0c;test&#xff1a;414张标注文件为YOLO适用的txt格式。可以直接用于模型训…

利用LaTeX写学位论文使用biblatex生成盲评的成果列表

利用LaTeX写学位论文使用biblatex生成盲评的成果列表 引言 在之前的文章《latex参考文献中修改指定作者的格式来突出显示》&#xff0c;我们介绍了在LaTeX中利用参考文献的方式生成学位论文的成果列表&#xff0c;而且将其中的作者突出显示。 但这种方式是用于明评的&#xf…

建筑物检测系统源码分享

建筑物检测检测系统源码分享 [一条龙教学YOLOV8标注好的数据集一键训练_70全套改进创新点发刊_Web前端展示] 1.研究背景与意义 项目参考AAAI Association for the Advancement of Artificial Intelligence 项目来源AACV Association for the Advancement of Computer Visio…

C语言-结构体-详解

博客主页&#xff1a;【夜泉_ly】 本文专栏&#xff1a;【C语言】 欢迎点赞&#x1f44d;收藏⭐关注❤️ C语言-结构体-详解 1.前言2.结构体类型2.1声明2.2变量的创建与初始化2.3访问2.4匿名结构体类型 3.结构体内存对齐3.1对齐规则3.2示例 1.前言 在C语言中&#xff0c;除了整…

MyBatis 增删改查【后端 17】

MyBatis 增删改查 引言 MyBatis 是一个优秀的持久层框架&#xff0c;它支持定制化 SQL、存储过程以及高级映射。MyBatis 避免了几乎所有的 JDBC 代码和手动设置参数以及获取结果集。MyBatis 可以使用简单的 XML 或注解用于配置和原始映射&#xff0c;将接口和 Java 的 POJOs (…

挑战力扣高难度算法、数据库题

一.算法类 1622题,困难,奇妙序列 class Fancy { public:static const int MOD 1e9 7;long long M_total; // cumulative multiplicative factorlong long A_total; // cumulative additive factorvector<long long> val; // original valuesvector<long long> …

PTrade量化服务器连接openapi的地址、key等配置涉及哪些文件?

量化服务器连接openapi的地址、key等配置涉及哪些文件&#xff1f; 1、/home/fly/data/BasicInfo/asset_config.yml中OPEN_API_URL配置为OPENAPI行情地址&#xff1b; 2、/home/fly/config/general_config.conf中client_id配置为OPENAPI行情app_key&#xff0c;client_secret配…

将YYYY-MM-DD HH:mm:ss格式化为YYYY-MM-DD (星期一) 下午 ?点

分为凌晨、早上、中午、晚上 function formatDate(inputDate) {const date new Date(inputDate);date.setHours(date.getHours() - 1);const year date.getFullYear();const month date.getMonth() 1; // 月份从0开始const day date.getDate();let hours date.getHours(…

Spring为什么要用三级缓存解决循环依赖?

Spring为什么要用三级缓存解决循环依赖&#xff1f; 1. Spring是如何创建一个bean对象2. Spring三级缓存2.1 一级缓存&#xff1a;单例池&#xff0c;经历过完整bean生命&#xff0c;单例Bean对象2.2 二级缓存&#xff1a;提前暴露的Bean2.3 三级缓存&#xff1a;打破循环 3. S…

三年 Sparker 都不一定知道的算子内幕

一、如何在 mapPartitions 中释放资源 mapPartitions是一种对每个分区进行操作的转换操作&#xff0c;于常用的map操作类似&#xff0c;但它处理的是整个分区而不是单个元素。mapPartitions的应用场景适合处理需要在每个分区内批量处理数据的场景&#xff0c;通常用于优化性能…

AJAX 进阶 day4

目录 1.同步代码和异步代码 2.回调函数地狱和 Promise 链式调用 2.1 回调函数地狱 2.2 Promise - 链式调用 2.3 Promise 链式应用 3.async 和 await 使用 3.1 async函数和await 3.2 async函数和await_捕获错误 4.事件循环-EventLoop 4.1 事件循环 4.2 宏任务与微任务…

【有啥问啥】对比学习(Contrastive Learning,CL)的原理与前沿应用详解

对比学习&#xff08;Contrastive Learning&#xff0c;CL&#xff09;的原理与前沿应用详解 对比学习&#xff08;Contrastive Learning&#xff09;是自监督学习领域的关键方法之一&#xff0c;近年来因其在图像、文本和跨模态任务上的优越表现&#xff0c;受到了学术界和工…

【重学 MySQL】三十、数值类型的函数

【重学 MySQL】三十、数值类型的函数 基本函数角度与弧度互换函数三角函数指数与对数进制间的转换示例 基本函数 MySQL提供了一系列基本的数值函数&#xff0c;用于处理数学运算和数值转换。以下是一些常用的基本函数及其用法&#xff1a; 函数用法ABS(x)返回x的绝对值。SIGN…

Linux下文件下载中文乱码问题

最近做的一个项目中&#xff0c;本地打包到线上后&#xff0c;发现生成的文件中出现中文乱码&#xff0c;但在本地运行正常。经排查&#xff0c;文件输入输出流都指定了utf-8的编码格式&#xff0c;IDE的File Encodings也都是utf-8&#xff0c;Linux编码格式也是utf-8&#xff…

商务人士必备的精准翻译工具盘点

网易翻译是一款我外出游玩时候必备的翻译工具&#xff0c;最近没出去玩但是有更多的翻译需求了&#xff0c;为了方便在电脑上的操作我也找了不少翻译工具&#xff0c;这次一起分享给大家&#xff0c;看看哪款更得你的眼缘。 1.福昕在线翻译 链接直达&#xff1a;https://fany…

回归预测|基于灰狼优化正则化极限学习机的数据回归预测Matlab程序GWO-RELM 多特征输入单输出

回归预测|基于灰狼优化正则化极限学习机的数据回归预测Matlab程序GWO-RELM 多特征输入单输出 文章目录 一、基本原理1. 极限学习机&#xff08;ELM&#xff09;模型2. 灰狼优化算法&#xff08;GWO&#xff09;3. GWO-RELM回归预测流程总结 二、实验结果三、核心代码四、代码获…

C++——多线程编程(从入门到放弃)

进程&#xff1a;运行中的程序 线程&#xff1a;进程中的进程 线程的最大数量取决于CPU的核心数 一、将两个函数添加到不同线程中 demo&#xff1a;两个函数test01()和test02()&#xff0c;实现将用户输入的参数进行打印输出1000次 将这两个函数均放到独立的线程t1和t2中&…

【优化器】Optimizer——深度学习中的优化器是什么作用呢?

【优化器】Optimizer——深度学习中的优化器是什么作用呢&#xff1f; 【优化器】Optimizer——深度学习中的优化器是什么作用呢&#xff1f; 文章目录 【优化器】Optimizer——深度学习中的优化器是什么作用呢&#xff1f;1.什么是优化器&#xff1f;梯度下降法3. 常见的优化…