【JavaEE】——线程池大总结

8e19eee2be5648b78d93fbff2488137b.png

阿华代码,不是逆风,就是我疯,

你们的点赞收藏是我前进最大的动力!!希望本文内容能够帮助到你!

目录

 

引入:问题引入

一:解决方案

1:方案一——协程/纤程

(1)本质

2:方案二——线程池

(1)本质

(2)优缺点

(3)解释高效的原因

二:ThreadPoolExecutor(标准库线程池)

1:Java库中找

2:构造方法

(1)核心线程数

(2)最大线程数

(3)保持存活时间

(4)时间单位

(5)工作任务

(6)线程工厂

①工厂模式

(7)拒绝策略(面试高频)

①中止策略

②甩锅策略

③喜新厌旧

④忠贞不渝

三:Executors(工厂类)

1:.newFixedThreadPool(可以设定固定线程数目)

2:submit添加任务

​编辑3:线程池中线程数量问题

(1)前引

(2)线程任务的分类

①CPU密集型任务

②IO密集型任务

(3)分情况讨论

四:通过代码实现简单的线程池

1:思路

2:代码示例


 

引入:问题引入

在之前的学习中,我们了解到,为了降低频繁创建和销毁进程所带来的巨大开销,我们引入了轻量级进程的概念(线程)

现在若线程的数量进一步提升,那么线程的频繁创建和销毁所带来的资源消耗,我们也不能忽视了

所以我们进行优化,引入了“池”的概念:这里有许多种类的池,线程池,数据库连接池,进程池......(提前把需要用到的对象准备好,用完的 对象也不要直接扔掉,放到池子中以便下次使用)

一:解决方案

1:方案一——协程/纤程

注:可以理解为轻量级线程

(1)本质

通过用户态代码进行调度,不靠系统内核的调度器调度(节省了调度的开销)

注:在java21中“虚拟线程”就是这个意思。

       在用户代码中,协程是基于线程进行封装的。

       go是比较早支持协程的,因为语法简单就火了

2:方案二——线程池

(1)本质

提前创建好线程,需要用的时候直接从池子里拿出来用,用完了也不要释放而是返还回池子中。

(2)优缺点

①优点:节省了创建和销毁线程带来的资源消耗,更高效

②缺点:占用了内存空间

(3)解释高效的原因

从线程池里获取线程,是在用户态代码中进行调度,是可控的,高效的

从操作系统中获取线程,是在系统内核中进行完成的,不可控,低效。

d9d7e3ce0b0a4962bbfed46e54794091.png

二:ThreadPoolExecutor(标准库线程池)

1:Java库中找

注:打开网站Overview (Java Platform SE 8 ),找到对应的包和class类

0bd458fa4e224b228cdd4015390c97cc.png6e6683c97721479fafbf61c0300326da.png

2:构造方法

6e2ebb9fc3604278acb46a94525d104b.png

我们直接看带有7个参数的构造方法

(1)核心线程数

int corePoolSize

core(核心)pool(池)siz(大小)

 

(2)最大线程数

int maximumPoolSize

核心线程可以理解为公司的正式员工,不能轻易裁掉;

普通线程可以理解为公司的实习生,裁掉比较容易

最大线程数 =  核心线程数 +普通线程数

(3)保持存活时间

long keepAliveTime

(4)时间单位

TimeUnit unit

单位:s,min,hour.......

普通线程能空闲的最大时间,超过空闲时间限制,就会被移除线程池

还是用上述例子举例,实习生不能说开就开,假定摸鱼时间限制为1个小时,只要实习生摸鱼的时间小于1个小时就不会被开,超过就被开

(5)工作任务

BlockingQueue<Runnable>  workQueue

与定时器(上篇文章)相似,线程池可以持有多个任务

Runnable用来描述任务的主体

<>也可以写PriorityQueue优先级队列

(6)线程工厂

ThreadFactory threadFactory

①工厂模式

通过(“工厂类”)类里面的(不一定是静态的)方法,对方法内部的new对象进行构造,完成对象的初始化(相当于,给构造方法外面在套上一层方法——套娃“封装”)

1026669ae539467eba5db3feddc92d69.png

56d76f658d634176af0e1525b9c47803.png

 

(7)拒绝策略(面试高频)

RejectedExecutionHandler handler——

execution(执行)handler(操作者)

问题:试想,线程池中有一个阻塞队列,存放的线程数目已经达到最大荣达,这个时候还往里面存放,那么线程池会怎么办?

d00ce6ae559744cebd67b9a6568ccf83.png

①中止策略

.AbortPolicy ——

如果硬要在加新任务的话,线程池:我吃柠檬,lz新旧任务都不干了,抛出异常

651361d0a53a442aae9e3ae6feaec96d.png

②甩锅策略

.CallerRunsPolicy——

线程池:让交代给我这个任务的人自己完成这个线程,我才不干

③喜新厌旧

.DiscardOldestPolicy——

discard(丢弃)

线程池抛弃池中呆的最久最老的一个线程,迎接新欢(喜新厌旧)

④忠贞不渝

.DiscardPolicy——

丢弃要新添加的任务,继续我行我素执行线程池中本来就有的任务

三:Executors(工厂类)

因为ThreadPoolExecutor使用起来较为复杂,所以标准库中就封装了一下,提供了Executors这个版本(工厂类,在内部把ThreadPoolExecutor创建好了,并且设置了不同的参数)

1:.newFixedThreadPool(可以设定固定线程数目)

c4ea4d8220f54f039b6a7b0ccf4082f6.png

2:submit添加任务

package thread;

import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

public class ThreadDemon34 {
    public static void main(String[] args) {
        ExecutorService service = Executors.newFixedThreadPool(4);
        service.submit(new Runnable(){
            @Override
            public void run() {
                System.out.println("执行线程池中第一个任务");
            }
        });

    }
}

edd48773c8d94b3980f8bae858716683.png

返回值类型点进去

ac27eadab28f421b841c96ae04be4c54.png3:线程池中线程数量问题

(1)前引

我们知道,线程的运行效率,跟cpu的逻辑核心数直接相关,假设cpu的逻辑核心数为N,那线程的数量该是多少合适(2N?1.5N?N?..........)

(2)线程任务的分类

①CPU密集型任务

线程大部分时间都在CPU上运行,计算

②IO密集型任务

大部分时间都在等待IO(input,output)。例如:Scanner读取用户的输入

(3)分情况讨论

到底在线程池中添加多少线程数量合适呢?

如果线程多为CPU类型的,那线程数目尽量不要超过N

如果线程多为IO类型的,那线程数目就可以远远超过N

但是具体开发肯定是需要我们多次测试,通过观察系统资源消耗,来找出最合适的添加数目的。

四:通过代码实现简单的线程池

1:思路

大逻辑其实就是,把创建的任务提交上去,再把任务取出来,在run执行就可以了就是这么简单

我们用到的IDEA自带的顺序表,阻塞队列BlockingQueue都其实是一个工具罢了~~

2:代码示例

package thread;

import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.ArrayBlockingQueue;
import java.util.concurrent.BlockingQueue;
import java.util.concurrent.ExecutorService;

/**
 * Created with IntelliJ IDEA.
 * Description:
 * User: Hua YY
 * Date: 2024-09-27
 * Time: 16:48
 */


class MyThreadPoolExecutor{
    //2:创建一个顺序表来接收创建的线程
    private List<Thread> threadList = new ArrayList<>();
    //4创建一个容量合适的阻塞队列
    private BlockingQueue<Runnable> queue = new ArrayBlockingQueue(1000);
    //1:通过一个循环,n的值,来控制产生的线程的数量
    public MyThreadPoolExecutor(int n){
        for (int i = 0; i < n; i++) {
            Thread t = new Thread(()->{
                //6:把要做的任务从任务队列中不停地取出来,并且执行
                while(true){
                    try {
                        
                        //带有阻塞的take取出元素
                        Runnable runnable = queue.take();
                        runnable.run();
                    } catch (InterruptedException e) {
                        throw new RuntimeException(e);
                    }
                }

            });
            t.start();
            //3:
            threadList.add(t);
        }
    }
    //5:提交runnable到队列里面去
    public void submit(Runnable runnable) throws InterruptedException {
        queue.put(runnable);
    }
}
public class ThreadDemon35 {
    //大逻辑其实就是,把创建的任务提交上去,再把任务取出来,在run执行就可以了就是这么简单
    public static void main(String[] args) throws InterruptedException {
        MyThreadPoolExecutor executor = new MyThreadPoolExecutor(4);
        for (int i = 0 ; i < 1000 ; i++){
            //变量捕获
            int n = i;
            executor.submit(new Runnable() {
                @Override
                public void run() {
                    System.out.println("执行任务:" + n + "  " + "当前线程为:" + Thread.currentThread().getName());
                }
            });
        }
    }
}

2a747122a79e46c58058b5cb54441881.png

 

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

多输入多输出预测 | NGO-BP北方苍鹰算法优化BP神经网络多输入多输出预测(Matlab)

多输入多输出预测 | NGO-BP北方苍鹰算法优化BP神经网络多输入多输出预测&#xff08;Matlab&#xff09; 目录 多输入多输出预测 | NGO-BP北方苍鹰算法优化BP神经网络多输入多输出预测&#xff08;Matlab&#xff09;预测效果基本介绍程序设计往期精彩参考资料 预测效果 基本介…

计算机毕业设计 在线问诊系统的设计与实现 Java实战项目 附源码+文档+视频讲解

博主介绍&#xff1a;✌从事软件开发10年之余&#xff0c;专注于Java技术领域、Python人工智能及数据挖掘、小程序项目开发和Android项目开发等。CSDN、掘金、华为云、InfoQ、阿里云等平台优质作者✌ &#x1f345;文末获取源码联系&#x1f345; &#x1f447;&#x1f3fb; 精…

市场调研利器 网络问卷的优势及面临的挑战

网络问卷作为市场调研工具&#xff0c;高效便捷、成本低廉、数据准确度高且灵活多样。但其低响应率、数据偏差、隐私与安全及技术依赖等挑战也需关注。企业应优化调研方法&#xff0c;应对挑战&#xff0c;以获取全面市场信息。 一、网络问卷的优势 首先&#xff0c;我们来分析…

vue3 通过 axios + jsonp 实现根据公网 ip, 查询天气信息

前提 安装 axios 的 jsonp 适配器。 pnpm install pingtou/axios-jsonp 简单使用说明&#xff1a;当与后端约定的请求 callback 参数名称不为为 callback 时&#xff0c;可修改。一般无需添加。 1. 获取当前电脑 ip 和城市信息 请求地址&#xff1a; https://whois.pconl…

国庆假节高速免费通行全攻略

关注▲洋洋科创星球▲一起成长&#xff01; 国庆节假期全国收费公路继续对7座以下&#xff08;含7座&#xff09;小型客车免收车辆通行费。 具体免费时段从 10月1日00&#xff1a;00开始 10月7日24&#xff1a;00结束 01 提前出发&#xff0c;免费离开&#xff1a; 如果你在…

视频分割怎么弄?国内外Top 7视频剪辑软件大盘点,新媒体必看!

视频是一种记录美好回忆的工具&#xff0c;无论过去的经历是搞笑还是尴尬&#xff0c;我们总能与他人一同回味那些时光。如果您对某部电影中的特定片段情有独钟&#xff0c;您可以寻找视频分割工具&#xff0c;轻松地对视频进行剪切和合并。分割视频的过程就像剪纸&#xff0c;…

【Oauth2整合gateway网关实现微服务单点登录】

文章目录 一.什么是单点登录&#xff1f;二.Oauth2整合网关实现微服务单点登录三.时序图四.代码实现思路1.基于OAuth2独立一个认证中心服务出来2.网关微服务3产品微服务4.订单微服务5.开始测试单点登录 一.什么是单点登录&#xff1f; 单点登录&#xff08;Single Sign On&…

代码随想录算法训练营第十七天|654.最大二叉树 617.合并二叉树 700.二叉搜索树中的搜索 98.验证二叉搜索树

654.最大二叉树 给定一个不含重复元素的整数数组。一个以此数组构建的最大二叉树定义如下&#xff1a; 二叉树的根是数组中的最大元素。左子树是通过数组中最大值左边部分构造出的最大二叉树。右子树是通过数组中最大值右边部分构造出的最大二叉树。 通过给定的数组构建最大二…

江科大笔记——新建工程

STM32的开发方式 目前STM32的开发方式主要有基于寄存器的方式、基于标准库的方式&#xff08;库函数的方式&#xff09;、基于HAL库的方式&#xff1a; 基于库函数的方式是使用ST官方提供的封装好的函数&#xff0c;通过调用这些函数来间接地配置寄存器。基于HAL库的方式可以…

【Linux】初始进程

目录 基本概念 PCB task_struct task_struct内容分类 组织进程 查看进程 查看正在运行的进程信息 获取pid和ppid 创建子进程 基本概念 一个已经加载到内存中的程序&#xff0c;叫做进程&#xff0c;正在运行的程序&#xff0c;叫做进程&#xff0c;进程是担当分配系统…

解决QT开发由于中文导致的编译错误以及输出内容乱码问题

在进行QT程序开发时&#xff0c;大家可能或者一定会遇到的问题就是中文乱码问题&#xff0c;这个乱码问题可能是在你看代码的显示上&#xff0c;也可能在程序的输出上&#xff0c;甚至还有可能导致你的代码直接编译失败&#xff0c;都有可能和中文编码有关&#xff0c;还有一些…

【Day20240924】联邦学习中的方法 改进

文章目录 前言一、FedAvg二、FedProx三、MOON四、FedDyn五、FedAsync六、PORT七、ASO-Fed八、FedBuff九、FedSA 前言 几种异步的方法&#xff1a; FedAsync PORT ASO-Fed FedBuff FedSA 几种同步的方法&#xff1a; FedAvg FedProx MOON FedDyn 一、FedAvg FedAvg基本步骤&a…

[SAP ABAP] 锁对象

在SAP中使用锁对象&#xff0c;用于避免在数据库中插入或更改数据时出现不一致的情况 1.创建锁对象 数据准备 学校表(ZDBT_SCH_437) 使用事务码SE11创建锁对象 点击"锁对象"单选按钮&#xff0c;输入以E开头的锁定对象的名称&#xff0c;然后点击创建按钮 锁对象名…

QT基础 制作简单登录界面

作业&#xff1a; 1、创建一个新项目&#xff0c;将默认提供的程序都注释上意义 01zy.pro代码 QT core gui # QT表示要引入的类库 core&#xff1a;核心库例如IO操作在该库中 gui&#xff1a;图形化界面库 # 如果要使用其他类库中的相关函数&#xff0c;则需要加对…

如何使用ssm实现基于web的学生就业管理系统的设计与实现+vue

TOC ssm726基于web的学生就业管理系统的设计与实现vue 第1章 绪论 1.1 课题背景 二十一世纪互联网的出现&#xff0c;改变了几千年以来人们的生活&#xff0c;不仅仅是生活物资的丰富&#xff0c;还有精神层次的丰富。在互联网诞生之前&#xff0c;地域位置往往是人们思想上…

努比亚z17努比亚NX563j原厂固件卡刷包下载_刷机ROM固件包下载-原厂ROM固件-安卓刷机固件网

努比亚z17努比亚NX563j原厂固件卡刷包下载_刷机ROM固件包下载-原厂ROM固件-安卓刷机固件网 统版本&#xff1a;官方软件作者&#xff1a;热心网友rom大小&#xff1a;911MB发布日期&#xff1a;2018-12-23 努比亚z17努比亚NX563j原厂固件卡刷包下载_刷机ROM固件包下载-原厂RO…

虚幻引擎游戏保存/加载存档功能

函数名功能Does Save Game Exist检查存档是否存在Load Game from Slot加载存档Save Game to Slot保存存档Delete Game in Slot删除存档 Slot Name 是插槽名字 存档都是通过插槽名字来 读取/加载/检查/删除的 先创建一个SaveGame类 , 这个类里可以存放要保存的数据 , 比如 玩家…

CSS 浏览器兼容问题探讨

目录 非 VIP 用户可前往公众号回复“css”进行免费阅读 浏览器介绍 css 选择器兼容介绍 ie6 微型盒子兼容解决方法 ie6双倍margin div中放入一个img元素导致div高度多出几像素 非 VIP 用户可前往公众号回复“css”进行免费阅读 浏览器介绍 在国内,常见的网页浏览…

华为认证HCIA篇--网络通信基础

大家好呀&#xff01;我是reload。今天来带大家学习一下华为认证ia篇的网络通信基础部分&#xff0c;偏重一些基础的认识和概念性的东西。如果对网络通信熟悉的小伙伴可以选择跳过&#xff0c;如果是新手或小白的话建议还是看一看&#xff0c;先有个印象&#xff0c;好为后续的…

机器学习:opencv--特征检测

目录 前言 一、 Harris 角点检测 1.基本思想 2.代码实现 二、 SIFT&#xff08;尺度不变特征变换&#xff09; 1.代码实现 前言 特征检测是计算机视觉中的一个重要任务&#xff0c;旨在从图像中提取具有辨识度的关键点或区域。这些特征可以用于后续的图像分析、匹配和识别…