【JUC-4】线程池实战应用

news2024/11/16 1:51:16

线程池

线程池创建方式

Executors创建线程池(不推荐)

JDK提供的工具类Execurtors创建线程池(不推荐), 列举几个Executors中创建线程池的方法; 查看Executors的源代码发现, 它创建线程池也是通过 new ThreadPoolExecutor() 来创建线程池的. 当然其中有一些特殊的线程池也不是通过ThreadPoolExecutor来创建的。 比如newWorkStealingPool(int parallelism) 方法就是通过ForkJoinPool来创建线程池的. 也有通过ScheduledThreadPoolExecutor创建调度线程池的方法.

固定大小线程池源码:

    public static ExecutorService newFixedThreadPool(int nThreads) {
        return new ThreadPoolExecutor(nThreads, nThreads,
                                      0L, TimeUnit.MILLISECONDS,
                                      new LinkedBlockingQueue<Runnable>());
    }

Executors中方法列表:

方法描述
newFixedThreadPool(int nThreads)创建一个固定大小的线程池,该线程池中的线程数量始终为指定的数量。
newCachedThreadPool()创建一个根据需要自动调整大小的线程池。当有任务提交时,如果有空闲线程,则会重用空闲线程执行任务;该线程池没有缓冲队列
newSingleThreadExecutor()创建一个只包含单个线程的线程池。线程池中只有一个线程,用于顺序执行任务。
newScheduledThreadPool(int corePoolSize)创建一个具有指定核心线程数的定时任务线程池。可以用于执行定时任务和周期性任务
newWorkStealingPool(int parallelism)创建一个具有指定并行度的工作窃取线程池。该线程池基于ForkJoinPool实现,用于执行计算密集型任务。线程池中的线程数量为指定的并行度。

ThreadPoolExecutor创建线程池(推荐)

实际开发中, 也是经常通过ThreadPoolExecutor通过自定义指定核心线程数/最大线程数/缓冲队列/拒绝策略 来创建线程池的.

ThreadPoolExecutor类图

在这里插入图片描述

ThreadPoolExecutor参数说明:

public ThreadPoolExecutor(int corePoolSize, int maximumPoolSize, long keepAliveTime, TimeUnit unit, BlockingQueue<Runnable> workQueue, ThreadFactory threadFactory, RejectedExecutionHandler handler)


  • corePoolSize:线程池的核心线程数,即线程池中始终保持的活动线程数量,即使它们处于空闲状态。当有新任务提交时,线程池会优先创建核心线程来执行任务。
  • maximumPoolSize:线程池允许的最大线程数,包括核心线程和非核心线程。当工作队列已满且当前线程数小于最大线程数时,线程池会创建新的线程来执行任务。如果设置为无界值(Integer.MAX_VALUE),则最大线程数没有限制。
  • keepAliveTime:非核心线程的空闲时间超过该值时,会被回收(终止)。即当线程池中的线程数量大于核心线程数,并且空闲时间超过keepAliveTime时,多余的线程会被回收,直到线程数量不超过核心线程数。
  • unit:空闲时间的时间单位,例如TimeUnit.SECONDS表示秒。
  • workQueue:用于保存待执行任务的阻塞队列。可以使用不同类型的阻塞队列,如ArrayBlockingQueueLinkedBlockingQueueSynchronousQueue等。选择合适的队列类型可以影响线程池的行为。

​ 除了上述参数之外,ThreadPoolExecutor还提供了其他构造函数和一些可选的参数,例如:

  • ThreadFactory:用于创建新线程的工厂类。可以自定义线程的名称、优先级等属性。

  • RejectedExecutionHandler:当线程池无法接受新任务时,定义了新任务的拒绝策略。常见的拒绝策略包括抛出异常、丢弃任务、丢弃队列中最旧的任务等。

    ThreadPoolExecutor中默认实现了4种拒绝策略

    1. AbortPolicy(默认):当线程池无法接受新任务时,会抛出RejectedExecutionException异常,拒绝新任务的提交。
    2. CallerRunsPolicy:当线程池无法接受新任务时,新任务会由提交任务的线程执行,而不是交给线程池中的线程执行。这样可以降低任务提交的速度,但可能会影响原始任务提交线程的性能。
    3. DiscardPolicy:当线程池无法接受新任务时,会直接丢弃新任务,不做任何处理。新任务被丢弃后,不会给出任何提示或记录。
    4. DiscardOldestPolicy:当线程池无法接受新任务时,会丢弃队列中最旧的任务,然后尝试重新提交新任务。

    也可以通过实现RejectedExecutionHandler接口来自定义拒绝策略.

线程池的状态

  1. 运行(Running):线程池处于正常运行状态,可以接受任务提交,并且正在执行任务。
  2. 关闭(Shutdown):调用了线程池的 shutdown() 方法后,线程池处于关闭状态。线程池不再接受新的任务提交,但会继续执行已提交的任务,直到所有任务完成。
  3. 停止(Stopped):调用了线程池的 shutdownNow() 方法后,线程池处于停止状态。线程池不再接受新的任务提交,并且尝试中断正在执行的任务。已提交但尚未开始执行的任务可能会被丢弃。
  4. 终止(Terminated):当线程池处于关闭状态且所有任务都已完成时,线程池进入终止状态。此时,线程池中的所有线程都已停止。

ThreadPoolExecutor方法列表

方法说明
Future submit(Callable c)向线程池提交任务,由线程池调度线程执行任务
List<Future> invokeAll(Collection<? extends Callable> tasks)invokeAll传入一个任务集合,由线程池调度执行集合中全部任务; 调用该方法,会阻塞主线程. 直到线程池中任务运行
T invokeAny(Collection<? extends Callable> tasks)T invokeAny(Collection<? extends Callable> tasks)
void shutdown()改变线程池状态为shutdown, 不再接受新的任务提交, 会将缓冲队列中的任务执行完
List shutdownNow()不会接受新的任务, 将队列中的任务返回, 并且使用interrupt方法打断正在执行的线程

线程池设置多少个线程数比较合适

CPU密集型:

CPU核数 + 1能够实现CPU最佳利用率; +1 是保证当操作系统页缺失故障时, 或其他原因导致暂停时, 额外的线程就能工作, 保证CPU时钟周期不被浪费.

IO密集型:

线程数 = 核数 * 期望CPU利用率 * 总时间(CPU计算时间+等待时间) / CPU计算时间

例如 2核CPU计算时间是 20%, 它的等待时间就是 80% , 期望CPU利用率是90%, 套用公式:

2 * 90% * 100% / 20% = 9

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

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

相关文章

Moka AI产品后观察:HR SaaS迈进AGI时代

在AI这条路上&#xff0c;Moka已经走了很远。如今的Moka Eva是在此前AI模型基础上的更进一步。未来AGI时代&#xff0c;HR SaaS会有更多可能性。 出品|产业家 在AI潮水里&#xff0c;Moka正在加速快跑。 在6月28日的2023夏季新品发布会上&#xff0c;国内首个AI原生HR Saa…

流量卡收货地就是归属地,这是什么意思呢?

我们在网上申请流量卡时&#xff0c;会比较关注流量卡归属地这一问题&#xff0c;据小编了解&#xff0c;目前网上的流量卡归属地有两种模式&#xff0c;接下来&#xff0c;小编一一为大家介绍一下&#xff0c;大家可以根据自己的情况来选择。 ​ 在中国的手机号码都有固定的区…

【MySQL】备份数据(导出数据 / 导入数据)

&#x1f3af;导出数据 1、使用 SELECT ... INTO OUTFILE 语句导出数据 SELECT...INTO OUTFILE 是 MySQL 用于导出数据的语句&#xff0c;它允许将查询结果保存到指定的文件中。 该语句的基本语法如下&#xff1a; SELECT column1, column2, ... INTO OUTFILE file_path …

Kotlin~Template模版方法模式

概念 定义算法骨架、代码模版 角色介绍 Abstract ClassConcrete Class UML 代码实现 abstract class Game {protected abstract fun initialize()protected abstract fun startPlay()protected abstract fun endPlay()// 模版fun play(){initialize()startPlay()endPlay()…

Spring面试题--Spring中事务失效的场景有哪些

Spring中事务失效的场景有哪些&#xff1f; 异常捕获处理 Transactional public void update(Integer from, Integer to, Double money) {try {//转账的用户不能为空Account fromAccount accountDao.selectById(from);//判断用户的钱是否够转账if (fromAccount.getMoney() - …

idea运行项目时右下角一直提示Lombok requires enabled annotation processing

出现这个错误是因为使用了Lombok插件的原因&#xff0c;可能是安装时候没有配置好 Lombok requires enabled annotation processing&#xff1a;翻译过来就是Lombok 需要启用注释处理 解决方案 File -> Settings ->Build,Execution,Deployment -> Compiler ->An…

35岁程序员现状,太真实!

“未来每年&#xff0c;我们将会为社会输送1000名工作10年以上的人才。” 这是之前马云在演讲中提到的关于阿里巴巴这样的大厂老员工的问题。总的来讲就是——“毕业”。 也经常能够看到在各个平台有程序员讲到自己35岁的焦虑。 之前&#xff0c;在某平台上就有一个有意思的…

Redis主从复制模式3

谋权篡位 假设在一个Redis集群中&#xff0c;有一台主机和两台从机构成一个Redis集群。此时因外部原因&#xff0c;导致主机宕机&#xff0c;俗话说 “国不可⼀一日无君&#xff0c;军不可一日无帅”&#xff0c;那么需要从剩余的两台从机中再次选出一台主机&#xff0c;从而来…

【小沐学Unity3d】Unity插件之绳索模拟Obi Rope

文章目录 1、简介2、安装3、示例测试3.1 Chains3.2 Crane3.3 ElectricalWires3.4 FreightLift3.5 Rocker3.6 RopeAndJoints3.7 RopeShowcase 4、简单测试结语 1、简介 https://assetstore.unity.com/packages/tools/physics/obi-rope-55579 Obi 是一款基于粒子的高级物理引擎…

本地部署 Chatbot UI,一个开源的 ChatGPT UI

openchat-ui 0. 什么是 Chatbot UI1. Github 地址2. 本地部署3. (参考)配置文件说明 0. 什么是 Chatbot UI Chatbot UI 是一个用于 AI 模型的开源聊天 UI。适用于 OpenChat 模型。 画面效果展示如下&#xff0c; 1. Github 地址 https://github.com/imoneoi/openchat-ui 2.…

Docker安装RabbitMQ docker安装RabbitMQ完整详细教程

Docker安装RabbitMQ docker安装RabbitMQ完整详细教程 Docker 上安装 RabbitMQ 3.12 的步骤&#xff1a;选择要安装的RabbitMQ 版本1、拉取 RabbitMQ 镜像2、创建并运行容器3、RabbitMQ 常用端口以及作用4、访问 管理页面测试&#xff0c;是否启动成功关闭容器启动容器 5、Docke…

OpenResty cosocket

cosocket 是各种 lua-resty-* 非阻塞库的基础 cosocket coroutine socket 需要 Lua 协程特性的支持&#xff0c;也需要 Nginx 事件机制的支持&#xff0c;两者结合在一起实现非阻塞网络 I/O。 遇到网络 I/O 时会交出控制权&#xff0c;把网络事件注册到 Nginx 监听列表中&a…

OpenSSH 用户枚举漏洞(CVE-2018-15473) 漏洞修复

OpenSSH 用户枚举漏洞&#xff08;CVE-2018-15473&#xff09;漏洞修复 1 漏洞说明2 漏洞修复3 相关问题 1 漏洞说明 2 漏洞修复 查看当前openssh版本&#xff1a; [rootizr0a05u4qferpr7yfhtotz ~]# ssh -V OpenSSH_7.4p1, OpenSSL 1.0.2k-fips 26 Jan 2017 [rootizr0a05u4…

ChatGLM-6B一键安装,马上使用(windows)!!

产品特点 双语&#xff1a; 同时支持中文和英文。 高精度&#xff08;英文&#xff09;&#xff1a; 在公开的英文自然语言榜单 LAMBADA、MMLU 和 Big-bench-lite 上优于 GPT-3 175B&#xff08;API: davinci&#xff0c;基座模型&#xff09;、OPT-175B 和 BLOOM-176B。 高…

MiniKube安装教程,简易版k8s,带你用最简单的方法体验k8s(学习环境通用)

Minikube安装教程 minikube 是本地 Kubernetes&#xff0c;专注于让 Kubernetes 易于学习和开发&#xff0c;这能很方便的在本地进行k8s学习&#xff0c;减轻初学者对于k8s的安装困难。&#xff08;信我&#xff0c;新手入门k8s就用这个够用了&#xff01;先别去折腾生产环境的…

[pyqt5]右键窗口弹出菜单并触发菜单点击事件

from PyQt5.Qt import * import sysclass MyWindow(QWidget):# 自定义窗体def contextMenuEvent(self, evt: QContextMenuEvent) -> None:menu QMenu(self)new_action QAction(打开, menu)new_action.triggered.connect(self.open)close_action QAction(关闭, menu)close…

Jupyter的安装与启动

一、简介 Jupyter Notebook&#xff08;此前被称为 IPython notebook&#xff09;是一个交互式笔记本&#xff0c;支持运行 40 多种编程语言。 Jupyter Notebook是一个开源的Web应用程序&#xff0c;允许用户创建和共享包含代码、方程式、可视化和文本的文档&#xff0c;支持…

【编码魔法师系列_六大原则2】里氏替换原则(Liskov Substitution Principle LSP Principle)

学会设计模式&#xff0c;你就可以像拥有魔法一样&#xff0c;在开发过程中解决一些复杂的问题。设计模式是由经验丰富的开发者们&#xff08;GoF&#xff09;凝聚出来的最佳实践&#xff0c;可以提高代码的可读性、可维护性和可重用性&#xff0c;从而让我们的开发效率更高。通…

BKP备份寄存器RTC实时时钟

BKP本质上是RAM寄存器&#xff0c;不能完全掉电不丢失&#xff0c;它的数据需要VBAT引脚提供的备用电源来维持。RTC复位和掉电不丢失是通过BKP来实现的。 目录 Unix时间戳 简介 计时标准​编辑 时间戳转换​编辑 示例代码 BKP 简介 BKP基本结构 RTC RTC简介 RTC框图 RT…

【100个 Unity实用技能】 | Unity中Text文本框 和 InputField文本输入框 内容换行问题【文末送书】

&#x1f3ac; 博客主页&#xff1a;https://xiaoy.blog.csdn.net &#x1f3a5; 本文由 呆呆敲代码的小Y 原创&#xff0c;首发于 CSDN&#x1f649; &#x1f384; 学习专栏推荐&#xff1a;Unity系统学习专栏 &#x1f332; 游戏制作专栏推荐&#xff1a;游戏制作 &…