手把手带你了解《线程池》

news2024/9/22 5:28:27

文章目录

    • 线程池的概念
    • 池的目的
    • 线程池的优势
    • 为什么从池子里拿线程更高效?
    • 构造方法参数讲解
    • 线程拒绝策略
    • 模拟实现线程池
    • 一个线程池设置多少线程合适?

线程池的概念

线程池:提前把线程准备好,创建线程不是直接从系统申请,而是从池子里拿,线程不用了还给池子。
复用线程,平摊线程的创建与销毁的开销代价

池的目的

池的目的是提高效率,线程的创建虽然比进程轻量,频繁创建,开销也不可忽略

线程池的优势

1、避免了线程的重复创建与开销带来的资源消耗代价
2、提升了任务响应速度,任务来了直接选一个线程执行而无需等待线程的创建
3、线程的统一分配和管理,也方便统一的监控和调优

为什么从池子里拿线程更高效?

从池子里拿线程:纯粹的用户态操作。
从系统创建线程:涉及到用户态和内核态的切换,真正的切换是在内核态完成的。

结论:纯用户态操作时间可控,涉及到内核操作不可控。

构造方法参数讲解

在这里插入图片描述

参数说明
corePoolSize核心线程数
maximumPoolSize最大线程数
keepAliveTime线程保持存活时间
TimeUnit unit时间单位
workQueue因为线程池要管理很多任务,这些任务通过阻塞队列来阻止的,程序员可以手动给线程池一个阻塞队列。submit方法就是把任务放到队列中
threadFactory工厂模式,创建线程的辅助类
handler线程池拒绝策略

线程拒绝策略

在这里插入图片描述
1、如果满了,继续添加任务,添加操作跑出异常。
2、添加的线程自己负责执行这个任务。
3、丢弃最老任务
4、丢弃最新的任务

模拟实现线程池

package Test1;

import java.util.concurrent.BlockingQueue;
import java.util.concurrent.LinkedBlockingQueue;

public class ThreadDemo3 {
    //阻塞队列,添加任务
    private BlockingQueue<Runnable>queue=new LinkedBlockingQueue<>();
    //将任务添加到队列中
    public void submit(Runnable runnable){
        try {
            queue.put(runnable);
        } catch (InterruptedException e) {
            throw new RuntimeException(e);
        }
    }
    //定义线程数量
    public ThreadDemo3(int n){
        for(int i=1;i<=n;i++){
            Thread t=new Thread(()->{
                while(true) {
                    try {
                        Runnable runnable = queue.take();//取任务
                        runnable.run();//执行任务
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }
            });
            //启动线程
            t.start();
        }
    }
}

一个线程池设置多少线程合适?

首先
线程并不是越多越好,多少合适取决于CPU。
其次
不同程序,线程要做的活也不一样;
1、CPU密集型任务,主要做一些计算工作,要在CPU上运行。
2、IO密集型任务,主要是等待IO操作,不咋吃CPU
假设,你的线程全是任务全是使用CPU密集型任务,线程数就不能超过核心数(逻辑核心数),如果是IO任务则可以超过核心数。
但是具体还是要通过测试方式来确定(计算执行时间,同时检测资源使用状态,测试多次取均值)。

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

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

相关文章

【linux】——日志分析

文章目录 1. 日志文件1.1 日志文件的分类1.2 日志文件保存位置1.2.1 内核及系统日志1.2.2 日志消息的级别1.2.3 日志记录的一般格式1.2.4 用户日志分析 程序日志分析日志管理策略 远程收集日志 1. 日志文件 1.1 日志文件的分类 ● 日志文件是用于记录Linux系统中各种运行消息的…

Flutter PC桌面端 控制应用尺寸是否允许放大缩小

一、需求 桌面端中&#xff0c;登录、注册、找回密码页面不允许用户手动放大缩小&#xff0c;主页面允许 二、插件 window_manager 使用教程请参照这篇博客&#xff1a;Flutter桌面端开发——window_manager插件的使用 题外话&#xff1a; 之前使用的是bitsdojo_window插件…

202303-第四周-山川软件产品资讯

山川软件愿为您提供最优质的服务。 您的每一个疑问都会被认真对待&#xff0c;您的每一个建议都将都会仔细思考。 我们希望人人都能分析大数据&#xff0c;人人都能搭建应用。 因此我们将不断完善DEMO、文档、以及视频&#xff0c;期望能在最大程度上快速帮助用户快速解决问…

3、Typescript中补充的六个类型

1、元组 元组可以看做是数组的拓展&#xff0c;它表示已知元素数量和类型的数组。确切地说&#xff0c;是已知数组中每一个位置上的元素的 类型&#xff0c;来看例子&#xff1a; let tuple: [string, number, boolean]; tuple ["a", 2, false]; tuple [2, "…

FPGA | 延迟模型

实际逻辑元器件和它们之间的传输路径都会存在延迟。因此&#xff0c;必须检查设计中的延迟是否满足实际电路的时序约束要求。可以用时序仿真的方法来检查时序&#xff08;timing&#xff09;&#xff0c;即在仿真时向元件或路径中加入和实际相符的延迟信息&#xff0c;并进行相…

4.34、组播(多播)

4.34、多播 1.组播(多播)的介绍①组播地址②如何设置组播&#xff08;组播的使用&#xff09; 2.代码编写①服务端②客户端 1.组播(多播)的介绍 单播地址标识单个 IP 接口&#xff0c;广播地址标识某个子网的所有 IP 接口&#xff0c;多播地址标识一组 IP 接口。单播和广播是寻…

ThreadPoolExecutor原理剖析

1.前言 1.1 为什么要使用线程池&#xff1f; 线程池主要为了解决两个问题 一是当执行大量异步任务时&#xff0c;线程池能够提供较好的性能&#xff0c;避免了重复创建和销毁线程带来的开销二是线程池提供了一种资源限制和管理的手段&#xff0c;比如限制线程个数&#xff0…

【蓝桥杯】最难算法没有之一· 动态规划真的这么好理解?(引入)

欢迎回到&#xff1a;遇见蓝桥遇见你&#xff0c;不负代码不负卿&#xff01; 目录 一、何为动态规划DP 二、记忆化搜索 典例1.斐波那契数列 方法一&#xff1a;暴力递归 方法二&#xff1a;记忆化搜索 变形题 典例2&#xff1a;爬楼梯&#xff08;青蛙跳台阶&#xf…

海睿思分享 | 低而不LOW的低代码开发

低代码&#xff08;Low-Code&#xff09; 是指输出最少的代码&#xff0c;快速完成软件系统开发&#xff0c;进而实现降低开发成本的成效。 Low-Code 中的“Low”与网络热词“LOW”同音同字&#xff0c;前者通常理解为低成本或少量的代码输出&#xff0c;后者是对低认知已见问…

【数据结构】数据结构小试牛刀之单链表

【数据结构】数据结构小试牛刀之单链表 一、目标二、实现1、初始化工作2、单链表的尾插2.1、图解原理2.2、代码实现解答一个疑问 3、单链表的尾删3.1、图解原理3.2、代码实现 4、打印单链表5、单链表的头插5.1、图解原理5.2、代码实现 6、单链表的头删6.1、图解原理6.2、代码实…

【Linux系统】理解Linux中进程间通信

Linux进程间通信 1 进程间通信的介绍1.1为什么要有进程间通信1.2 为什么能进程间通信 2 进程间通信的框架2.1 进程间通信机制的结构2.2 进程间通信机制的类型2.2.1 共享内存式2.2.2 消息传递式 2.3 进程间通信的接口设计 3 进程间通信机制简介4 详细讲解进程间通信部分机制&…

【OAuth2.0 Client 总结】对接github第三方登录以及其他第三方登录总结

之前搞 oauth 登录一直没有搞好&#xff0c;客户端、授权服务端、资源端一起搞对于我刚接触的小菜鸡来说&#xff0c;难度有点大。 然后就先搞了个 Client 端对接 Github 登录。 网上关于 Github 登录的资料有很多&#xff0c;而且框架对 Github 集成的也很好&#xff0c;配置起…

【深入解析K8S专栏介绍】

序言 时间永远是旁观者&#xff0c;所有的过程和结果&#xff0c;都需要我们自己去承担。 Kubernetes (k8s) 是一个容器编排平台&#xff0c;允许在容器中运行应用程序和服务。 专栏介绍 欢迎订阅&#xff1a;【深入解析k8s】专栏 简单介绍一下这个专栏要做的事&#xff1a; 主…

8年测试老兵竟被面试官10分钟pass,这也太难了吧...

前言 随着软件测试领域对于技术要求越来越清晰&#xff0c;到现在测试人员在市场上的岗位需求也变得越来越复杂。极大部分的企业都开始对自动化测试岗位有了更多的需要。自然而然&#xff0c;面试就相对于非常重要了。 笔试部分 1.阐述软件生命周期都有哪些阶段&#xff1f;…

stm32cubemx IAP升级(二)

stm32cubemx IAP升级- App的制作 板卡&#xff1a;Nucleo-L412 平台&#xff1a;macbook pro 工具&#xff1a;vscode stm32cubemx stm32cubeProgramer cmake toolchain 整体思路 将App设置为从0x08007000地址启动&#xff0c;然后初始化一路串口用作接收上位机的升级数据&a…

docker容器:docker镜像的三种创建方法及dockerfile案例

目录 一、基于现有镜像创建 1、创建启动镜像 2、生成新镜像 二、基于本地模板创建 1、OPENVZ 下载模板 2、导入容器生成镜像 三、基于dockerfile创建 1、dockerfile结构及分层 2、联合文件系统 3、docker镜像加载原理 4、dockerfile操作常用的指令 (1)FROM指令 (…

kotlin协程flow retry retryWhen(2)

kotlin协程flow retry retryWhen&#xff08;2&#xff09; 一、retry import kotlinx.coroutines.flow.* import kotlinx.coroutines.runBlockingfun main(args: Array<String>) {runBlocking {(1..5).asFlow().onEach {if (it 3) {println("-")throw Runti…

入行IC选择国企、私企还是外企?(内附各IC大厂薪资福利情况)

不少人想要转行IC&#xff0c;但不知道该如何选择公司&#xff1f;下面就来为大家盘点一下IC大厂的薪资和工作情况&#xff0c;欢迎大家在评论区补充。 一&#xff0e;老 牌 巨 头 在 IC 设计领域深耕许久&#xff0c;流程完善、技术扎实&#xff0c;公司各项制度都很完善、前…

关于改造维护工单BAPI_ALM_ORDER_MAINTAIN用于生产订单组件批量修改

1、研究背景 1.1、业务背景 由于销售、研发、工艺等需要频繁变更&#xff0c;导致工单中组件需要频繁的进行变更&#xff0c;修改组件的物料&#xff0c;数量&#xff0c;库存地点&#xff0c;工序等内容。 1.2、技术痛点 为了满足要求&#xff0c;使用了函数&#xff1a;CO…

FVM链的Themis Pro(0x,f4) 5日IDO超百万美元,或让Filecoin逆风翻盘

交易一直是DeFi乃至web3领域最经久不衰的话题&#xff0c;也因此催生了众多优秀的去中心化协议&#xff0c;如Uniswap和Curve。这些协议逐渐成为了整个系统的基石。 在永续合约方面&#xff0c;DYDX的出现将WEB2时代的订单簿带回了web3。其链下交易的设计&#xff0c;仿佛回到了…