【JAVAEE】线程池基础知识⭐

news2024/11/25 0:41:43

目录

1.什么是线程池

2.为什么要使用线程池

3.怎么使用线程池

4.自定义一个线程池

5.为什么不推荐使用系统自带的线程池

5.1线程池构造方法的参数和含义

5.1.1拒绝策略

5.2线程池的工作原理

5.3为什么不适用系统自带的线程池

补充:工厂模式


1.什么是线程池

在JDBC编程中,通过DataSource获取Connection连接的时候就已经用到了的概念,当Java程序需要数据库连接的时候就从池中拿一个空闲的连接对象给Java程序,Java程序用完了连接之后就会返回给连接池。

线程池就是在池中放的是线程本身,当程序启动的时候就创建出若干个线程,如果有任务就处理,没有任务就等待。

百度百科的定义为:

线程池是一种多线程处理形式,处理过程中将任务添加到队列,然后在创建线程后自动启动这些任务。线程池线程都是后台线程。

2.为什么要使用线程池

使用线程池可以减少系统创建线程的损耗。

如下图:创建线程需要申请PCB

 线程池的作用就是为了减少这些关于申请和释放PCB的操作,尽量保证我们的程序在用户态执行,不牵扯到硬件层面。

3.怎么使用线程池

JDK给我们提供了一些方法来创建线程池:

        // 1. 用来处理大量短时间工作任务的线程池,如果池中没有可用的线程将创建新的线程,如果线程空闲60秒将收回并移出缓存
        ExecutorService cachedThreadPool = Executors.newCachedThreadPool();
        // 2. 创建一个操作无界队列且固定大小线程池
        ExecutorService fixedThreadPool = Executors.newFixedThreadPool(3);
        // 3. 创建一个操作无界队列且只有一个工作线程的线程池
        ExecutorService singleThreadExecutor = Executors.newSingleThreadExecutor();
        // 4. 创建一个单线程执行器,可以在给定时间后执行或定期执行。
        ScheduledExecutorService singleThreadScheduledExecutor = Executors.newSingleThreadScheduledExecutor();
        // 5. 创建一个指定大小的线程池,可以在给定时间后执行或定期执行。
        ScheduledExecutorService scheduledThreadPool = Executors.newScheduledThreadPool(3);
        // 6. 创建一个指定大小(不传入参数,为当前机器CPU核心数)的线程池,并行地处理任务,不保证处理顺序
        Executors.newWorkStealingPool();

这里使用第2个方法进行基本使用示例:

先创建一个线程池:

//创建一个线程池
ExecutorService threadPoll= Executors.newFixedThreadPool(3);

此时线程池中已经存在了一些创建好的线程,只需要往线程池中提交任务即可。

这里采用for循环,提交十个任务(打印“我是任务几”):

        //提交任务到线程池
        for (int i = 0; i < 10; i++) {
            int taskId = i;
            threadPoll.submit(() -> {
                System.out.println("我是任务 " + taskId + ","+"Thread.currentThread().getName());
            });
        }

 任务被提交到线程池后,任务就会被自动执行。

4.自定义一个线程池

1.可以提交任务到线程池,那么就会有一种数据结构来保存我们提交的任务,这里可以考虑用阻塞队列来保存任务。

2.创建线程池需要指定初始线程数量,这些线程不停的扫描阻塞队列,如果有任务就立即执行。可以考虑使用线程池对象的构造方法,接收要创建线程的数量,并在构造方法中完成线程的创建。

实现过程:

1.定义一个阻塞队列来保存我们的任务

    //1.定义一个阻塞队列
    BlockingDeque<Runnable>queue=new LinkedBlockingDeque<>(3);

2.定义一个方法提交任务

    //2.对外提供一个方法用来往队列中提交任务
    public void submit(Runnable task) throws InterruptedException {
        queue.put(task);
    }

3.定义构造方法

    //3.构造方法,完成线程的创建,扫描队列,取出任务并执行
    public MyThreadPoll(int capacity){
        if(capacity<=0){
            throw new RuntimeException("线程数量不能小于0");
        }
        for (int i = 0; i < capacity; i++) {
            Thread thread=new Thread(()->{
                while(true) {
                    try {
                        //取出任务
                        Runnable take = queue.take();
                        //执行任务
                        take.run();
                    } catch (InterruptedException e) {
                        throw new RuntimeException(e);
                    }
                }
            });
            //启动线程
            thread.start();
        }
    }

测试一下代码:

    public static void main(String[] args) throws InterruptedException {
        //创建自定义的线程池
        MyThreadPoll myThreadPoll=new MyThreadPoll(3);
        //往线程池中提交任务
        for (int i = 0; i < 10; i++) {
            int taskId=i;
            myThreadPoll.submit(()->{
                System.out.println("我是任务 " + taskId + ", " + Thread.currentThread().getName());
            });
        }
    }

执行成功,测试通过。

5.为什么不推荐使用系统自带的线程池

5.1线程池构造方法的参数和含义

通过工厂方法获取的线程池,最终都是ThreadPoolExecutor类的对象。

ThreadPoolEexecutor各参数含义:

corePoolSize:核心线程数,创建线程池时包含的最小线程数量

maximumPoolSize:最大线程数,也可以叫做临时线程数,当核心数不够用的时候,允许系统可以创建的最多线程数是多少

keepAliveTime:临时线程空闲的时长

TimeUnit unit:空闲的时间单位,和keepAliveTime配合使用

BlockingQueue<Runnable>workQueue:用来保存任务的阻塞队列

ThreadFactory:线程工厂,如何去创建线程,用系统默认的就可以

RejectedExecutionHandler:拒绝策略,触发的时机,当线程池处理不了过多的任务时触发

 举例说明:

5.1.1拒绝策略

拒绝策略有4中,根据自己的业务场景选择合适的拒绝策略即可。

5.2线程池的工作原理

这七个参数搭配使用:

1.当任务添加到线程池中时,先判断任务数是否大于核心线程数

2.如果不大于直接执行,否则加入阻塞队列

3.当阻塞队列满了之后,会按指定的线程最大数创建临时线程

4.当阻塞队列满了,而且临时线程也创建完成,再提交任务时,执行拒绝策略

5.当任务减少,临时线程达到空闲时长时,会被回收

5.3为什么不适用系统自带的线程池

 

 

补充:工厂模式

工厂模式是我们最常用的实例化对象模式了,是用工厂方法代替new操作的一种模式。

先来看看一个代码示例:

定义一个Student类,定义有参构造

由于重载过程,参数列表相同而报错 。

使用工厂方法:

 

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

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

相关文章

stm32 74hc595外扩io 调试记录

本文使用的测试代码如下 (1条消息) stm3274hc595外扩io调试工程&#xff0c;软件代码2片74hc595级联外扩IO资源-CSDN文库 有个项目对成本比较敏感&#xff0c;又想用ST的片子&#xff0c;输出管脚比较多&#xff0c;就考虑外扩IO&#xff0c;也有一些外扩IO的片子但是用下来成…

视频理解AI模型分类与汇总

人工智能领域视频模型大体也经历了从传统手工特征&#xff0c;到卷积神经网络、3D卷积网络、双流网络、transformer的发展脉络。 视频的技术大多借鉴图像处理技术&#xff0c;只是视频比图片多了一个时间维度。 下面内容先简单汇总下&#xff0c;后续再逐渐补充。 1. 双流网…

DS200SLCCG1AFG随着频率的增加而增加。具有高 Dk 的基材将具有高 Df。

​ DS200SLCCG1AFG随着频率的增加而增加。具有高 Dk 的基材将具有高 Df。 Df 耗散因数&#xff08;又名损耗角正切&#xff09; Df 测量由于电阻加热而损失了多少功率。PCB 基板形成电容器作为绝缘体&#xff0c;导体通常位于两侧。作为电容器&#xff0c;它会表现出容抗&#…

MySQL---聚合函数、字符串函数、数学函数、日期函数

1. 聚合函数 数据准备&#xff1a; create database mydb4; use mydb4;create table emp(emp_id int primary key auto_increment comment 编号,emp_name char(20) not null default comment 姓名,salary decimal(10,2) not null default 0 comment 工资,department char(20…

激光切割机要换新该怎么选?如何减少激光加工设备的老化问题?

激光器的销量持续攀高&#xff0c;激光切割机的应用领域涉及众多行业。随着加工范围和厚度的提升&#xff0c;运行多年的中低功率 激光切割机已经不能满足时下很多设备加工的需求&#xff0c;要提企业的加工能力&#xff0c;选择一款新的激光加工设备已是势在必行。 激光切割机…

Ubuntu使用(持续更新中)

文章目录 1.以root身份登录2.配置apt源3.安装Docker3.1BUG: 4.在VMware中克隆Ubuntu5.配置apt国内源 额 我们项目用的CentOS7,由于CentOS8停止了维护,客户反馈了这个问题,所以玩一下Ubuntu,我使用的是Ubuntu Serve LST,如有不同,另行百度 1.以root身份登录 Ubuntu默认是不开启r…

java异常的声明、捕获、抛出、处理(throws、throw、try-catch详解)

异常的处理 LBYL: Look Before You Leap. 在操作之前就做充分的检查. 即&#xff1a;事前防御型 boolean ret false; ret 登陆游戏(); if (!ret) { 处理登陆游戏错误; return; } ret 开始匹配(); if (!ret) { 处理匹配错误; return; } ret 游戏确认(); if (!ret) { 处理游…

在职读研是理想还是情怀?你想要的都将在社科大能源管理硕士项目实现

在职读研是理想还是情怀呢&#xff0c;每个读研人的想法不同&#xff0c;原因也有所不同。但选择在职继续攻读硕士学位的群体也有着共同点&#xff0c;他们都是想拥有高学历&#xff0c;拥有高目标的一群人。探寻新的起点和终点是他们想所要追求的。不管读研的初心是什么&#…

Figma怎么导出PDF文件?

Figma 是一款备受网页和 UI 设计师喜爱的基于矢量的设计工具。其最大的优势在于方便用户与团队成员进行协作。当设计师需要与其他团队成员、设计师或客户共享设计文件时&#xff0c;设计师需要将设计图案导出为 PDF 格式以方便查看。同样地&#xff0c;当设计师需要将设计图稿打…

优维低代码实践:数据模型设计

优维低代码技术专栏&#xff0c;是一个全新的、技术为主的专栏&#xff0c;由优维技术委员会成员执笔&#xff0c;基于优维7年低代码技术研发及运维成果&#xff0c;主要介绍低代码相关的技术原理及架构逻辑&#xff0c;目的是给广大运维人提供一个技术交流与学习的平台。 优维…

msvcp110.dll丢失的解决方法,msvcp110.dll一键修复教程

昨天卸载了一个垃圾软件以后&#xff0c;我的ps软件就无法打开运行&#xff0c;提示msvcp110.dll丢失&#xff0c;无法继续执行此代码。今天早上找了很多方法&#xff0c;终于把msvcp110.dll丢失的原因以及修复的方法都弄明白了。msvcp110.dll是一个非常重要的文件&#xff0c;…

【Python】【进阶篇】30、Django模板继承精讲

目录 30、Django模板继承精讲1. 模板继承的概念2. 模板继承的应用3. 父模板内容扩展(block.super)4. 总结归纳 30、Django模板继承精讲 在本节我们讲述模板语言中最后一个知识点&#xff0c;也是最重要的&#xff0c;那就是模板继承。模板继承和 Python 语言中类的继承含义是一…

敏捷专题:下一代的飞机交付

随着信息化和网络化的发展&#xff0c;航空航天领域的装备已经发展成为软件密集型系统&#xff0c;软件负责完成航空装备的大部分功能。资料显示&#xff0c;以美国的F-22战斗机为例&#xff0c;由软件实现的功能已经达到80%以上&#xff0c;航空航天领域的软件规模和重要度与日…

【MySql】数据建模

目录 一&#xff1a;概念 二&#xff1a;数据建模 三&#xff1a;E-R模型 1.1E-R模型之chen方法 1.2E-R模型之crows foot方法 1.3E-R模型之idef 1x方法 一&#xff1a;概念 现实世界---->信息世界(概念模型[E-R模型])---->计算机世界(数据模型[关系、网状和层次模型])…

20230512-VSCode-配置C++17-win11-22h2

20230512-VSCode-配置C17-win11-22h2 一、软件环境 标签&#xff1a;C VSCode w64devkit gcc12分栏&#xff1a;C操作系统&#xff1a;Windows11 x64 22h2编译器&#xff1a;vscode-1.78.2 w64devkit-1.18.0 二、操作步骤 1. 下载安装VScode 官网 打开官网【https://code…

深度学习笔记——数值稳定性、模型初始化与激活函数

机器学习笔记——数值稳定性、模型初始化与激活函数 引言数值稳定性——梯度爆炸小插曲&#xff1a;关于对角阵 Diag [ σ ′ ( W t ⋅ h t − 1 ) ] \text{Diag}[\sigma(\mathcal W_t \cdot h_{t-1})] Diag[σ′(Wt​⋅ht−1​)]的解释梯度爆炸的问题 如何让参数更新更加稳定方…

移动机器人运动规划---基于图搜索的基础知识---配置空间

配置空间 机器人规划的配置空间概念&#xff1a;一个空间包含所有机器人自由度的机器人配置&#xff0c;描述为C-space 机器人配置&#xff1a;表示对机器人上面所以点的位置的描述机器人自由度&#xff1a;规划的时候用最少的坐标数量去表示机器人配置&#xff0c;例如无人机…

NFTScan: 蓝筹 NFT 跌幅严重,如何保持竞争力?

最近的市场大跌影响了 NFT 二级市场&#xff0c;市场情绪冷淡下跌严重&#xff0c;交易量和买家骤然下降&#xff0c;而蓝筹作为市场里的中流砥柱也表现不佳。以 BoerdApeYachtClub 为首的等主流 NFT 价格下跌超过 20%。此外&#xff0c;随着 PFP 的热潮已经过去&#xff0c;市…

【文章学习系列之模型】DLinear

本章内容 文章概况模型流程实验定量结果定性结果其他对比 总结 文章概况 《Are Transformers Effective for Time Series Forecasting?》是2023年发表于AAAI上的一篇文章。该文章以“Transformer在时序预测中是否有效”为论点展开讨论&#xff0c;并提出一种非Transformer系列…

SwiftUI 4.0 中 List 显示层级数据的子视图在展开和收起操作时无动画的解决

问题现象 在 SwiftUI 4.0(iOS 16+)中,一个超简单 List 视图层级子视图的收放操作竟然没有动画,这着实有点让人不爽: 从上图可以看到:我们在点击 List 子项时不仅毫无收放动画可言,而且在展开时还有卡顿,显得非常生硬。 以上代码在目前最新的 iOS 16.4.1(a) 系统中测试…