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

Java中的线程池你了解多少?

         🌈🌈🌈今天给大家分享的是Java标准库中的线程池,以及线程池的自定义实现。

清风的CSDN博客

       🛩️🛩️🛩️希望我的文章能对你有所帮助,有不足的地方还请各位看官多多指教,大家一起学习交流!🛩️🛩️🛩️

✈️✈️✈️动动你们发财的小手,点点关注点点赞!在此谢过啦!哈哈哈!✈️✈️✈️

目录

一、线程池是什么 

 二、认识Java标准库中的线程池 

2.1 使用线程池

三、简单线程池自定义实现 


 

一、线程池是什么 

虽然创建线程 / 销毁线程 的开销不大。但是我们想象一下下面的场景:

         学校附近新开了一家快递店,老板很精明,想到一个与众不同的办法来经营。店里没有雇人,而是每次有业务来了,就现场找一名同学过来把快递送了,然后解雇同学。这个类比我们平时来一个任务,起一个线程进行处理的模式。
         很快老板发现问题来了,每次招聘 + 解雇同学的成本还是非常高的。老板还是很善于变通的,知道了为什么大家都要雇人了,所以指定了一个指标,公司业务人员会扩张到 3 个人,但还是随着业务逐步雇人。于是再有业务来了,老板就看,如果现在公司还没 3 个人,就雇一个人去送快递,否则只是把业务放到一个本本上,等着 3 个快递人员空闲的时候去处理。这个就是我们要带出的线程池的模式。

 二、认识Java标准库中的线程池 

 其中,ExecutorService service 是一个线程池对象。Executors.newFixedThreadPool()是创建线程池的过程。Executors称为“工厂类”。newFixedThreadPool() 是工厂方法。这里涉及到的设计模式是“工厂模式”。什么是“工厂模式”?工厂,顾名思义,就是负责“生产”的。一般创建对象,都是通过构造方法来new对象。但是构造方法,存在重大缺陷。此时就可以使用工厂模式来解决问题。

构造方法存在什么样的缺陷呢?Java中规定构造方法的名字必须和类名相同,而有的类,需要有多种不同的构造方式,但是构造方法名字又固定,此时就只能通过构造方法的重载(要求参数的个数和类型要有差别)来满足实现多种不同的构造方式。我们来举一个例子:

假设现在需要有一个类:Point 类,(描述平面上的一个点),第一种典型的构造方式,使用笛卡尔坐标来构造:

class Point{public Point(double x, double y){}
}

第二章典型的构造方式,使用极坐标系来构造:

public Point(double r,double a){//r为半径,a为角度}

此时,问题就出现了,我们明明是想按照两种方式进行构造,但是这两个构造方式,参数的个数和类型是一样的,无法构成重载,编译器会报错。此时构造方法的缺陷就体现出来了。

要解决上述问题,可以通过“工厂模式”的方案。

不使用构造方法了,使用普通方法来构造对象,这样,方法名字就可以是任意的了。在普通方法内部去 new 对象,由于普通方法的目的是为了创建出对象来,这样的方法一般得是静态的。

class Point{public static void makePointXY(double x, double y){//在普通方法里new对象}public static void makePointRA(double r, double a){//在普通方法里new对象}
}

后续再创建对象,就可以这样创建:

  Point p = Point.makePointRA(10,20);Point p1 = Point.makePointXY(5.5,6.5);

这样的操作,就叫做“工厂”设计模式,上面的方法也叫做“工厂方法”。

创建一个固定线程数量的线程池: 

 创建一个线程数目动态变化的线程池:

 创建一个包含单个线程的线程池:

2.1 使用线程池

线程池对象创建(工厂模式创建)好之后,使用submit方法,就可以把任务添加到线程池中。

  public static void main(String[] args) {ExecutorService service = Executors.newFixedThreadPool(4);for (int i = 0; i < 100; i++) {service.submit(new Runnable() {@Overridepublic void run() {System.out.println("hello");}});}}

调用submit方法,创建100各打印“hello”的任务。

除了上述这些线程池之外,标准库还提供了一个接口更丰富的线程池类,“ThreadPoolExecutor"。 

上述提供的创建线程池的工厂方法,都是对 ThreadPoolExecutor 的一个封装,是为了使用方便。

这个ThreadPoolExecutor有很多可以供我们调整的选项,更好的满足实际需求。我们来看一下Java标准库中对于ThreadPoolExecutor 的介绍。

 

 

 这里,我们了解了最后一种构造方法,其他的构造方法也就很好理解了。

 

表示核心线程数(至少得有这些线程,哪怕当前线程池没有任务)

 

 表示最大线程数(最多不能超过这些线程,哪怕当前线程池任务再多)

ThreadPoolExecutor 里面的线程个数并不是固定不变的,会根据当前任务的情况发生动态变化。

 

表示不是核心线程的线程,可以持续空闲的时间。

当不是核心线程的线程,到达这个指定的时间阈值后,就被自动销毁了。

 线程池内部有很多任务,这些任务可以使用阻塞队列来管理。(线程池可以内置阻塞队列,也可以手动指定阻塞队列)。

工厂模式,通过这个工厂类,创建线程。

 

拒绝策略/方式,线程池里有阻塞队列,当阻塞队列已满,继续添加任务,如何处理?标准库中也给出了现成的拒绝策略:

① 

  简而言之,直接抛出异常,线程池不干活了。

② 

 哪个线程添加了任务,就去负责执行这个任务。

丢弃最早的任务,执行新的任务。

 直接把新的任务丢弃。

三、简单线程池自定义实现 

class MyThreadPool{private BlockingQueue<Runnable> queue = new LinkedBlockingQueue<>();public void submit(Runnable runnable) throws InterruptedException {//通过这个方法,把任务添加到线程池中queue.put(runnable);}//创建固定数量的线程池public MyThreadPool(int n){//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 class Test {public static void main(String[] args) throws InterruptedException {MyThreadPool pool = new MyThreadPool(4);for (int i = 0; i < 100; i++) {pool.submit(new Runnable() {@Overridepublic void run() {//要执行的工作System.out.println(Thread.currentThread().getName()+"hello");}});}}
}

 


🌈🌈🌈好啦,今天的分享就到这里!

🛩️🛩️🛩️希望各位看官读完文章后,能够有所提升。

🎉🎉🎉创作不易,还希望各位大佬支持一下!

✈️✈️✈️点赞,你的认可是我创作的动力!

⭐⭐⭐收藏,你的青睐是我努力的方向!

✏️✏️✏️评论:你的意见是我进步的财富!

 

相关文章:

Java中的线程池你了解多少?

&#x1f308;&#x1f308;&#x1f308;今天给大家分享的是Java标准库中的线程池&#xff0c;以及线程池的自定义实现。 清风的CSDN博客 &#x1f6e9;️&#x1f6e9;️&#x1f6e9;️希望我的文章能对你有所帮助&#xff0c;有不足的地方还请各位看官多多指教&#xff0c;…...

leetCode 131.分割回文串 + 动态规划 + 回溯算法 + 优化 + 图解 + 笔记

我的往期文章&#xff1a; leetCode 647.回文子串 动态规划 优化空间 / 中心扩展法 双指针-CSDN博客https://blog.csdn.net/weixin_41987016/article/details/133883091?spm1001.2014.3001.5501leetCode 131.分割回文串 回溯算法 图解 笔记-CSDN博客https://blog.csdn.n…...

【傻瓜级JS-DLL-WINCC-PLC交互】3.JS-DLL进行交互

思路 JS-DLL-WINCC-PLC之间进行交互&#xff0c;思路&#xff0c;先用Visual Studio创建一个C#的DLL控件&#xff0c;然后这个控件里面嵌入浏览器组件&#xff0c;实现JS与DLL通信&#xff0c;然后DLL放入到WINCC里面的图形编辑器中&#xff0c;实现DLL与WINCC的通信。然后PLC与…...

深度学习手势识别算法实现 - opencv python 计算机竞赛

文章目录 1 前言2 项目背景3 任务描述4 环境搭配5 项目实现5.1 准备数据5.2 构建网络5.3 开始训练5.4 模型评估 6 识别效果7 最后 1 前言 &#x1f525; 优质竞赛项目系列&#xff0c;今天要分享的是 &#x1f6a9; 深度学习手势识别算法实现 - opencv python 该项目较为新颖…...

2023-12-01 AIGC-自动生成ppt的AI工具

摘要: 2023-12-01 AIGC-自动生成ppt-记录 自动生成ppt: BoardMix boardmix 一键生成ppt boardmix是一款基于云的ai设计软件&#xff0c;允许创建用于各种目的的自定义演示文稿、ai绘画&#xff0c;ai生成思维导图等。以下是它的一些功能&#xff1a; 可定制的模板 - 它有一个…...

NoSQL 数据建模错误会降低性能

数据建模错误是破坏性能的最简单方法之一。当您使用 NoSQL 时&#xff0c;特别容易搞砸&#xff0c;&#xff08;讽刺的是&#xff09;NoSQL 往往用于对性能最敏感的工作负载。NoSQL 数据建模最初可能看起来非常简单&#xff1a;只需对数据进行建模以适应应用程序的访问模式。但…...

在Android上搭建一个NDK项目

首先New Project&#xff0c;选择Native C&#xff0c;点击Next。 填入项目名称和包名&#xff0c;点击Next。 这里我们选择Cmake默认的C版本。 创建好的项目目录&#xff0c;里面比我们正常的Android项目多了一个cpp目录 打开MainActivity。里面定义了一个jni方法stringFromJN…...

TOP-K问题和向上调整算法和向下调整算法的时间复杂度问题的分析

TOP-K问题 TOP-K问题&#xff1a;即求数据结合中前K个最大的元素或者最小的元素&#xff0c;一般情况下数据量都比较大 比如&#xff1a;专业前10名、世界500强、富豪榜、游戏中前100的活跃玩家等 对于Top-K问题&#xff0c;能想到的最简单直接的方式就是排序&#xff0c;但是…...

3、服务器性能剖析

性能优化简介 **我们将性能定义为完成某件任务所需要的时间度量&#xff0c;换句话说&#xff0c;性能即响应时间&#xff0c;这是一个非常重要的原则。**我们通过任务和时间而不是资源来测量性能。数据库服务器的目的是执行sql语句&#xff0c;所以他关注的任务是查询或者语句…...

xxl-job 分布式任务调度框架

文章目录 分布式任务调度XXL-Job 简介XXL-Job 环境搭建XXL-Job (源码说明)配置部署调度中心docker安装 Bean模式任务(方法形式)-入门案例任务详解任务详解-执行器任务详解-基础配置任务详解-调度配置任务详解-基础配置任务详解-阻塞处理策略任务详解-路由策略 路由策略路由策略…...

软件使用-stm32入门

这节主要是介绍大家使用两个软件。这两个软件也是比较常用的&#xff0c;里面也有很多有意思的功能&#xff0c;可以给大家介绍一下。 1. FlyMcu 软件 这个软件可以通过串口给 STM32 下载程序&#xff0c;如果你没有 STLINK&#xff0c;就可以用这个软件通过串口下载程序。 …...

使用MAT分析内存泄漏(mac)

前言 今天主要简单分享下Eclipse的Memory Analyzer在mac下的使用。 一、Mat&#xff08;简称&#xff09;干什么的&#xff1f; 就是分析java内存泄漏的工具。 二、使用步骤 1.下载 mac版的现在也分芯片&#xff0c;别下错了。我这里是M2芯片的&#xff0c;下载的Arch64的。 …...

【Vue】Linux 运行 npm run serve 报错 vue-cli-service: Permission denied

问题描述 在Linux系统上运行npm run serve命令时&#xff0c;控制台报错&#xff1a; sudo npm run serve project50.1.0 serve vue-cli-service serve sh: 1: vue-cli-service: Permission denied错误截图如下&#xff1a; 原因分析 该错误是由于vue-cli-service文件权限不…...

LeetCode的几道题

一、捡石头 292 思路就是&#xff1a; 谁面对4块石头的时候&#xff0c;谁就输&#xff08;因为每次就是1-3块石头&#xff0c;如果剩下4块石头&#xff0c;你怎么拿&#xff0c;我都能把剩下的拿走&#xff0c;所以你就要想尽办法让对面面对4块石头的倍数&#xff0c; 比如有…...

NLP/Natural Language Processing

一、NLP是什么 自然语言处理( Natural Language Processing, NLP)是计算机科学领域与人工智能领域中的一个重要方向&#xff0c;也就是人们常说的「自然语言处理」&#xff0c;就是研究如何让计算机读懂人类语言&#xff0c;即将人的自然语言转换为计算机可以阅读的指令。它研…...

【教学类-06-12】20231202 0-9数字分合-房屋样式(一)-下右空-升序-抽7题

作品展示-屋顶分合&#xff08;0-9之间随机抽取7个不重复分合&#xff09; 背景需求&#xff1a; 大班幼儿学分合题&#xff0c;通常区角里会设计一个“房屋分合”的样式 根据这种房屋样式&#xff0c;设计0-9内的升序分合题模板 素材准备 WORD样式 代码展示&#xff1a; 2-9…...

uni-app 微信小程序 电子签名及签名图片翻转显示功能

文章目录 1. 需求背景2. 开始撸2.1 点击 重写 进入签名页面&#xff08;上图一&#xff09;2.2 书写签名&#xff0c;点击确认返回&#xff0c;及图片翻转显示&#xff08;上图二&#xff0c;三&#xff09; 3. 图片进行翻转&#xff0c;返回翻转后的图片 1. 需求背景 接的一个…...

MySQL 8.0关键字和保留字

官网地址&#xff1a; https://dev.mysql.com/doc/refman/8.0/en/keywords.html 可以粘贴出去自己排版整理 {accessible} {account} {action} {active} {add} {admin} {after} {against} {aggregate} {algorithm} {all} {alter} {always} {analyse} {analyze} …...

PyLMKit(3):基于角色扮演的应用案例

角色扮演应用案例RolePlay 0.项目信息 日期&#xff1a; 2023-12-2作者&#xff1a;小知课题: 通过设置角色模板并结合在线搜索、记忆和知识库功能&#xff0c;实现典型的对话应用功能。这个功能是大模型应用的基础功能&#xff0c;在后续其它RAG等功能中都会用到这个功能。功…...

JAVA全栈开发 集合详解(day14+day15汇总)

一、数组 数组是一个容器&#xff0c;可以存入相同类型的多个数据元素。 数组局限性&#xff1a; ​ 长度固定&#xff1a;&#xff08;添加–扩容&#xff0c; 删除-缩容&#xff09; ​ 类型是一致的 对象数组 &#xff1a; int[] arr new int[5]; … Student[] arr …...

Linux Spug自动化运维平台本地部署与公网远程访问

文章目录 前言1. Docker安装Spug2 . 本地访问测试3. Linux 安装cpolar4. 配置Spug公网访问地址5. 公网远程访问Spug管理界面6. 固定Spug公网地址 前言 Spug 面向中小型企业设计的轻量级无 Agent 的自动化运维平台&#xff0c;整合了主机管理、主机批量执行、主机在线终端、文件…...

zookeeper集群和kafka集群

&#xff08;一&#xff09;kafka 1、kafka3.0之前依赖于zookeeper 2、kafka3.0之后不依赖zookeeper&#xff0c;元数据由kafka节点自己管理 &#xff08;二&#xff09;zookeeper 1、zookeeper是一个开源的、分布式的架构&#xff0c;提供协调服务&#xff08;Apache项目&…...

Java——》JSONObjet 数据顺序

推荐链接&#xff1a; 总结——》【Java】 总结——》【Mysql】 总结——》【Redis】 总结——》【Kafka】 总结——》【Spring】 总结——》【SpringBoot】 总结——》【MyBatis、MyBatis-Plus】 总结——》【Linux】 总结——》【MongoD…...

【个人记录】NGINX反向代理grpc服务

最开始使用proxy_pass去代理了grpc服务&#xff0c;结果请求时候报错提示&#xff1a; rpc error: code Unavailable desc connection error: desc "error reading server preface: http2: frame too large"后来才知道代理grpc服务需要使用grpc_pass&#xff0c;…...

【小白推荐】安装OpenCV4.8 系统 Ubuntu 22.04LST Linux.

先看一下目录&#xff0c;知道大致的流程&#xff01; 文章目录 安装OpenCV安装依赖下载源码配置与构建安装 测试编写CMakeListx.txt编写测试代码 安装OpenCV 安装依赖 sudo apt update && sudo apt upgrade sudo apt install cmake ninja-build build-essential lib…...

使用Docker Compose搭建CIG监控平台

CIG简介 CIG监控平台是基于CAdvisor、InfluxDB和Granfana构建的一个容器重量级监控系统&#xff0c;用于监控容器的各项性能指标。其中&#xff0c;CAdvisor是一个容器资源监控工具&#xff0c;用于监控容器的内存、CPU、网络IO和磁盘IO等。InfluxDB是一个开源的分布式时序、时…...

前端文本省略号后面添加复制文字

前端文本省略号后面添加复制文字 1、效果图 2、代码展示 <div class"link-content-wrap" click"copyLinkText"><div class"link-content">{{ shareResult.url || }} </div><span class"show-ellipsis" click&…...

【算法】动态规划中的路径问题

君兮_的个人主页 即使走的再远&#xff0c;也勿忘启程时的初心 C/C 游戏开发 Hello,米娜桑们&#xff0c;这里是君兮_&#xff0c;如果给算法的难度和复杂度排一个排名&#xff0c;那么动态规划算法一定名列前茅。今天&#xff0c;我们通过由简单到困难的两道题目带大家学会动…...

代数学笔记9: 群的直积,可解群,自由群,群表示

群的直积 外直积 H 1 , H 2 H_1,H_2 H1​,H2​是两个群(固定的群), 且有 G H 1 H 2 GH_1\times H_2 GH1​H2​,(构造的新群) G ( { ( h 1 , h 2 ) ∣ h 1 ∈ H 1 , h 2 ∈ H 2 } , ⋅ ) , G\big(\{(h_1,h_2)|h_1\in H_1,h_2\in H_2\},\cdot\big), G({(h1​,h2​)∣h1​∈H…...

kali学习

目录 黑客法则&#xff1a; 一&#xff1a;页面使用基础 二&#xff1a;msf和Windows永恒之蓝漏洞 kali最强渗透工具——metasploit 介绍 使用永恒之蓝进行攻击 ​编辑 使用kali渗透工具生成远程控制木马 渗透测试——信息收集 域名信息收集 黑客法则&#xff1a; 一&…...