初识线程池

news/2024/11/25 11:05:47/

目录

  • 初识线程池
    • 为什么要引入线程池
    • 标准库中的线程池
    • 代码演示
    • 创建线程池的时候,设置多少个线程合适??

初识线程池

池 是一个非常重要的概念

你可能听说过 池化技术

常量池、数据库连接池、线程池、进程池、内存池…

为什么要引入线程池

最开始 ,进程就能解决 并发 编程问题。

因为频繁创建销毁进程,成本太高了,因此,引入了 轻量级 进程----->线程

如果创建销毁线程的频率进一步提高,此时线程的创建销毁开销,也就不能无视了!!!!

就需要想办法优化此处的线程的创建销毁效率

解决方案,有两种:

1.引入 轻量级 线程—>也称为 纤程/协程

2.线程池,把要使用的线程提前创建好,用完了也不要直接释放而是以备下次使用,就节省了创建/销毁线程的开销

在这个使用的过程中,并没有真的 频繁创建销毁,而只是从线程池里,取线程使用,用完了还给线程池

而且从线程池里取线程,是纯用户态代码,(可控的,直接拿)

通过系统申请创建线程,就是需要内核来完成的(不太可控,你不知道什么时候给你创建好)

标准库中的线程池

ThreadPoolExecutor

这个类的构造方法,有很多参数,侧面映射出线程池的设计思路了。
在这里插入图片描述
在这里插入图片描述
参数
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
线程池默认提供了四种拒绝策略,分别是AbortPolicy、CallerRunsPolicy、DiscardPolicy和DiscardOldestPolicy。

ThreadPoolExecutor.AbortPolicy:丢弃任务并抛出RejectedExecutionException异常。

ThreadPoolExecutor.DiscardPolicy:丢弃任务,但是不抛出异常。

ThreadPoolExecutor.DiscardOldestPolicy:丢弃队列最前面的任务,然后重新提交被拒绝的任务
ThreadPoolExecutor.CallerRunsPolicy:由调用线程(提交任务的线程)处理该任务

**==

代码演示

java">import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;public class ThreadDemo32 {public static void main(String[] args) {// 使用Executors工具类创建一个线程池,这里创建的是一个固定大小的线程池// newFixedThreadPool方法接受一个整数参数,表示线程池中的线程数量// 在本示例中,创建了一个包含4个线程的固定大小线程池ExecutorService service = Executors.newFixedThreadPool(4);// 向刚刚创建的线程池提交一个任务,任务以匿名内部类的形式实现了Runnable接口service.submit(new Runnable() {// 实现Runnable接口中的run方法,这个方法定义了任务具体要执行的内容@Overridepublic void run() {System.out.println("hello");}});// 注意:这里缺少了关闭线程池的操作}
}

创建线程池的时候,设置多少个线程合适??

假设一个极端情况:

如果一个进程中,所有的线程都是CPU密集型的,每个线程所有的工作都是CPU上执行的

此时,线程数目就不应该超过N(CPU逻辑核心数)

如果一个进程中,所有的线程都是IO密集型的,每个线程的大部分工作都是在等待IO,CPU消耗非常少

此时线程数目就可以很多,远远超过N

上述两个场景都是极端情况

实际上一个进程中的线程,大概率都是一部分是IO,一部分是CPU的

这里具体的比例,不好确定

综上,由于程序的复杂性,很难直接对于线程池的线程数量进行估算。

更合适的做法,----->通过实验/测试的方式找到合适的线程数目

尝试给线程池设定不同的线程数目,分别进行性能测试。

衡量每种线程数目下,总的时间开销,和系统资源占用的开销,找到这两者之间的合适的值


http://www.ppmy.cn/news/1549804.html

相关文章

IDEA优雅debug

目录 引言一、断点分类🎄1.1 行断点1.2 方法断点1.3 属性断点1.4 异常断点1.5 条件断点1.6 源断点1.7 多线程断点1.8 Stream断点 二、调试动作✨三、Debug高级技巧🎉3.1 watch3.2 设置变量3.3 异常抛出3.4 监控JVM堆大小3.5 数组过滤和筛选 引言 使用ID…

设计模式——前端控制器模式

定义与概念 前端控制器模式(Front Controller Pattern)是一种软件设计模式,主要用于集中处理 Web 应用或其他多层架构应用的请求。它作为一个单一的入口点来接收和处理所有的客户端请求,将请求分发给相应的处理模块,从…

【Spring源码核心篇-03】精通spring的aop的底层原理和源码实现

Spring源码核心篇整体栏目 内容链接地址【一】Spring的bean的生命周期https://zhenghuisheng.blog.csdn.net/article/details/143441012【二】深入理解spring的依赖注入和属性填充https://zhenghuisheng.blog.csdn.net/article/details/143854482【三】精通spring的aop的底层原…

移动光猫[HS8545M5-10]获取超密

移动光猫[HS8545M5-10]获取超级密码 1、缘由2、前期准备2.1、确保本地开通telnet客户端功能2.2、准备好相关软件 3、开始查找超密 1、缘由 最近想折腾一下ipv6ddns打通内外网,查询资料说是需要将光猫桥接到外网;但是使用光猫后边的用户名密码根本就找不到…

Android开发实战班 - 应用架构 - LiveData/Flow 数据流

在 MVVM 架构中,数据流是连接 ViewModel 和 View 的重要桥梁,用于实现数据的观察和响应。Jetpack 提供了两种主要的数据流机制:LiveData 和 Flow。本章节将深入讲解 LiveData 和 Flow 的概念、使用方法、区别以及在实际开发中的应用场景&…

Claude Opus MetaPrompt 系统详解

Claude Opus MetaPrompt 系统详解 简介 MetaPrompt系统是由Anthropic提出的,旨在帮助用户为AI助手Claude生成高质量的提示。它指导用户定义任务和变量、结构化指令和细化输出。 具体内容 特点 主要针对Claude 3 Opus版本,并且适用于单轮对话。 核心…

windows C#-生成和使用异步流(上)

异步流建立流式处理数据源模型。 数据流经常异步检索或生成元素。 它们为异步流式处理数据源提供了自然编程模型。 先决条件 需要将计算机设置为运行 .NET,包括 C# 编译器。 C# 编译器随附于 Visual Studio 2022 或 .NET SDK。 将需要创建 GitHub 访问令牌&#…

[系统安全]PE文件头中的重定位表

PE加载的过程 任何一个EXE程序会被分配4GB的内存空间,用户层处理低2G的内存,驱动处理高2G的内存。 1、双击EXE程序,操作系统开辟一个4GB的空间。2、从ImageBase决定了加载后的基址,ImageSize决定了程序有多大。3、然后加载DLL 大…