线程池相关知识点

news2024/11/28 16:02:25

线程池是什么相信大家都是知道的,所以这里就不做解释了,直接看相关知识点吧。

初始化线程池方法

继承ThreadPool

实现Runnable

实现Callable 接口+ FutureTask (可以拿到返回结果,可以处理异常)

核心参数

  • corePoolSize:核心线程数。(理解为某个公司的长期员工)
  • maximumPoolSize:最大线程数。(理解为当前公司项目太多,需要招募短期员工,这个时候长期员工+短期员工数量就是最大线程数)
    • 这里最大线程数需要大于核心线程数,不然会报错:
  • keepAliveTime:空闲线程存活时间。
  • TimeUnit:时间单位。
  • BlockingQueue:线程池任务队列。
    • ArrayBlockingQueue:一个由数组结构组成的有界阻塞队列。
    • LinkedBlockingQueue:一个由链表结构组成的有界阻塞队列。
    • SynchronousQueue:一个不存储元素的阻塞队列,即直接提交给线程不保持它们。
    • PriorityBlockingQueue:一个支持优先级排序的无界阻塞队列。
    • DelayQueue:一个使用优先级队列实现的无界阻塞队列,只有在延迟期满时才能从中提取元素。
    • LinkedTransferQueue:一个由链表结构组成的无界阻塞队列。与SynchronousQueue类似,还含有非阻塞方法。
    • LinkedBlockingDeque:一个由链表结构组成的双向阻塞队列。
  • ThreadFactory:创建线程的工厂。
  • RejectedExecutionHandler:拒绝策略。

任务队列等于阻塞队列?

  1. 任务队列(Task Queue)

    • 任务队列是线程池中用于存放待执行任务的队列。
    • 当一个任务被提交到线程池时,如果线程池中的工作线程数已达到最大值,或者所有工作线程都在忙碌,那么这个任务就会被放入任务队列中等待后续执行。
    • 任务队列可以是无界的(如LinkedBlockingQueue),也可以是有界的(如ArrayBlockingQueue),具体取决于线程池的配置。
  2. 阻塞队列(Blocking Queue)

    • 阻塞队列是一种特殊的队列,它支持线程安全的入队(put)和出队(take)操作。
    • 当队列为空时,从队列中取元素的操作(如take)会阻塞,直到队列中有元素可用。
    • 当队列已满时,向队列中添加元素的操作(如put)会阻塞,直到队列中有空间可用。
    • 阻塞队列是实现任务队列的一种常见方式,但不是唯一的方式。例如,SynchronousQueue也是一种任务队列,但它不存储元素,而是直接将元素从一个生产者线程传递给消费者线程。

因此,任务队列是线程池中用于管理待执行任务的队列,而阻塞队列是一种支持线程安全操作的队列。阻塞队列可以作为实现任务队列的一种方式,但任务队列的概念更广泛,不一定局限于阻塞队列。在线程池的上下文中,任务队列通常是指用于存放待执行任务的队列,而这个队列可以是基于阻塞队列实现的。

拒绝策略

  1. AbortPolicy(默认策略):直接抛出RejectedExecutionException异常,阻止系统正常运行。
  2. CallerRunsPolicy:主线程直接执行该任务,执行完之后尝试添加下一个任务到线程池中,可以有效降低向线程池内添加任务的速度。
  3. DiscardPolicy:直接丢弃无法处理的任务,不抛出异常,也不执行任务。
  4. DiscardOldestPolicy:丢弃最旧的任务请求,然后尝试再次提交当前任务。

线程池的运行流程

  1. 线程池创建,准备好core 数量的核心线程,准备接受任务
  2. 新的任务进来,用core 准备好的空闲线程执行。 (1) 、core 满了,就将再进来的任务放入阻塞队列中。空闲的core 就会自己去阻塞队 列获取任务执行 (2) 、阻塞队列满了,就直接开新线程执行,最大只能开到max 指定的数量 (3) 、max 都执行好了。Max-core 数量空闲的线程会在keepAliveTime 指定的时间后自 动销毁。最终保持到core 大小 (4) 、如果线程数开到了max 的数量,还有新任务进来,就会使用reject 指定的拒绝策 略进行处理
  3. 所有的线程创建都是由指定的factory 创建的。

一个线程池core 7; max 20 ,queue:50,100 并发进来怎么分配的; 先有7 个能直接得到执行,接下来50 个进入队列排队,在多开13 个继续执行。现在70 个 被安排上了。剩下30 个默认拒绝策略。拒绝策略一般是抛弃,如果不想抛弃还要执行,可以使用同步的方式执行,或者丢弃最老的。

四种常见的线程池

  1. newCachedThreadPool创建一个可缓存线程池 ,如果线程池长度超过处理需要,可灵活回收空闲线程,若 无可回收,则新建线程。核心线程固定是0,所有都可回收
  2. newFixedThreadPool创建一个固定长线程池,可控制线程最大并发数, 超出的线程会在队列中等待。固定大小,核心 = 最大
  3. newScheduledThreadPool创建一个固定长线程池,支持定时及周期性任务执行。 定时任务线程池
  4. newSingleThreadExecutor创建一个 单线程化的线程池 ,它只会用唯一的工作线程来执行任务,保证所有任务 按照指定顺序(FIFO, LIFO, 优先级)执行。后台从队列里面获取任务 挨个执行

SpringBoot整合线程池

1、添加配置类,新建线程池

package cn.cloud.xmall.product.config;

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

import java.util.concurrent.Executors;
import java.util.concurrent.LinkedBlockingQueue;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;


@Configuration
public class MyThreadConfig {

    @Bean
    public ThreadPoolExecutor threadPoolExecutor(){
       return new ThreadPoolExecutor(
                10,
                100,
                20,
                TimeUnit.SECONDS,
                new LinkedBlockingQueue<>(100000),
                Executors.defaultThreadFactory(),
                new ThreadPoolExecutor.AbortPolicy()
                );
    };
    

}

2.想要在配置文件中手动的配置参数 新建一个配置属性类

package cn.cloud.xmall.product.config;

import lombok.Data;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.context.annotation.Configuration;
import org.springframework.stereotype.Component;


@ConfigurationProperties(prefix = "mall.thread")
@Component  //加入容器
@Data
public class ThreadPollConfigProperties {
    private Integer coreSize;
    private Integer maxSize;
    private Integer keepAliveTime;
}

        可以在依赖种添加此依赖,在配置文件中就会有我们自己配置属性的提示

<dependency>
      <groupId>org.springframework.boot</groupId>
      <artifactId>spring-boot-configuration-processor</artifactId>
      <optional>true</optional>
  </dependency>

3.配置文件配置属性

#线程池配置
mall:
  thread:
    core-size: 10
    max-size: 100
    keep-alive-time: 20

4.使用配置文件中的属性

@
EnableConfigurationProperties(ThreadPollConfigProperties.class),如果配置文件类没有添加@Component加入容器可以使用这种方式

package cn.cloud.xmall.product.config;

import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.cache.annotation.EnableCaching;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

import java.util.concurrent.Executors;
import java.util.concurrent.LinkedBlockingQueue;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;


//@EnableConfigurationProperties(ThreadPollConfigProperties.class)
@Configuration
public class MyThreadConfig {

    @Bean
    public ThreadPoolExecutor threadPoolExecutor(ThreadPollConfigProperties pool){
       return new ThreadPoolExecutor(
                pool.getCoreSize(),
                pool.getMaxSize(),
                pool.getKeepAliveTime(),
                TimeUnit.SECONDS,
                new LinkedBlockingQueue<>(100000),
                Executors.defaultThreadFactory(),
                new ThreadPoolExecutor.AbortPolicy()
                );
    };


}

5.注入线程池

@Autowired

private ThreadPoolExecutor executor;

6.异步编排

@Override
    public SkuItemVo item(Long skuId) throws ExecutionException, InterruptedException {

        SkuItemVo skuItemVo = new SkuItemVo();

        //1.使用自己的线程池来新建异步任务
        CompletableFuture<SkuInfoEntity> infoFuture = CompletableFuture.supplyAsync(() -> {
            //1.查询基本信息 pms_sku_info
            SkuInfoEntity info = getById(skuId);
            skuItemVo.setInfo(info);
            return info;
        }, executor);

        //2.根据一号任务来继续调用
        CompletableFuture<Void> saleAttrFuture = infoFuture.thenAcceptAsync((res) -> {
            //3.获取当前spu的销售属性组合
            List<SkuItemSaleAttrVo> saleAttrVos = saleAttrValueService.getSaleAttrsBySpuId(res.getSpuId());
            skuItemVo.setSaleAttr(saleAttrVos);
        }, executor);

        //3.根据一号任务来继续调用
        CompletableFuture<Void> descFuture = infoFuture.thenAcceptAsync((res) -> {
            //4.获取Spu的介绍 pms_spu_info_desc
            SpuInfoDescEntity spuInfo = spuInfoDescService.getById(res.getSpuId());
            skuItemVo.setDesc(spuInfo);
        }, executor);

        //4.根据一号任务来继续调用
        CompletableFuture<Void> baseAttrFuture = infoFuture.thenAcceptAsync((res) -> {
            //5.获取spu的规格参数信息
            List<SpuItemAttrGroupVo> attrGroups = attrGroupService.getAttrGroupWithAttrsBySpuId(res.getSpuId(), res.getCatalogId());
            skuItemVo.setGroupAttrs(attrGroups);
        }, executor);

        //此任务不需要根据一号任务的返回调用,所以开一个新线程
        CompletableFuture<Void> imagesFuture = CompletableFuture.runAsync(() -> {
            //2.获取sku的图片信息 pms_sku_images
            List<SkuImagesEntity> images = imagesService.getImagesBySkuId(skuId);
            skuItemVo.setImages(images);
        }, executor);

        //等待所有任务都完成
        //TODO 可以选择有异常情况下的处理结果
        CompletableFuture.allOf(saleAttrFuture,descFuture,baseAttrFuture,imagesFuture).get();
        

        return skuItemVo;
    }

该文档后续会继续更新,希望读者可以在评论区留言我可以根据具体的问题进行更新~

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

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

相关文章

[米联客-XILINX-H3_CZ08_7100] FPGA程序设计基础实验连载-23 VTC视频时序控制器设计

软件版本&#xff1a;VIVADO2021.1 操作系统&#xff1a;WIN10 64bit 硬件平台&#xff1a;适用 XILINX A7/K7/Z7/ZU/KU 系列 FPGA 实验平台&#xff1a;米联客-MLK-H3-CZ08-7100开发板 板卡获取平台&#xff1a;https://milianke.tmall.com/ 登录“米联客”FPGA社区 http…

Javascript LeeCode选题(汉诺塔求解)

LeeCode选题 汉诺塔递归求解move移动函数hanoi函数main方法测试代码&#xff1a;代码实现 汉诺塔递归求解 汉诺塔介绍&#xff1a; 汉诺塔的的图形&#xff08;从上到下1&#xff0c;2&#xff0c;3个&#xff09;实现&#xff1a; 这里我们可以看到因为必须要将第n个移动到…

数据结构与算法 第7天(树和森林)

树 树的存储结构 双亲表示法 找双亲容易&#xff0c;找孩子不容易 孩子链表法 把每个结点的孩子节点排列起来&#xff0c;看成一个线性表&#xff0c;用单链表存 找孩子容易&#xff0c;找双亲难 带双亲孩子链表法 给孩子链表加一个参数&#xff0c;存双亲的下标 孩子兄…

系统思考—盲点

突‮盲破‬点&#xff0c;解‮合锁‬作潜能——JSTO 的‮能高‬碰撞&#xff01; 在今天的JSTO会议中&#xff0c;我们在Check In环‮分节‬享了近1-2周‮实的‬践和反思。这‮环个‬节不仅‮助帮‬大家‮享共‬了更多的‮息信‬和资源&#xff0c;还‮效有‬促进了彼‮间此‬…

jenv 一款macos下的开源JAVA多版本环境安装管理切换工具

一个用于macos/linux下的多版本JAVA环境管理工具 -- jenv, 这款工具和 pyenv 类似,都是基于shell脚本开发的. 可以方便的管理 多个java环境版本. jenv安装 git clone https://gitee.com/tekintian/jenv.git ~/.jenv jenv环境配置 将下面的代码加入都你的 ~/.bash_profil…

堆垛机知识介绍:附图

导语 大家好&#xff0c;我是社长&#xff0c;老K。专注分享智能制造和智能仓储物流等内容。 完整版文件和更多学习资料&#xff0c;请球友到知识星球【智能仓储物流技术研习社】自行下载。 这份文件是关于堆垛机的介绍&#xff0c;内容包括堆垛机的概念、分类、工作原理、结构…

Vue(九) 全局事件总线、Todo案例应用全局事件总线、消息订阅与发布、Todo案例应用消息订阅、编辑Item、$nextTick

文章目录 一、全局事件总线 (GlobalEventBus)1. 总线前言2. 安装全局事件总线3. 使用总线事件4. 解绑总线事件 二、Todo案例应用全局事件总线三、消息订阅与发布1. 前言2. 使用步骤 四、Todo案例应用消息订阅五、Todo案例编辑Item六、$nextTick修改后的Todo完整代码 一、全局事…

【负载均衡】LoadBalance场景演示

服务端⾼并发分布式结构演进之路-CSDN博客文章浏览阅读976次&#xff0c;点赞11次&#xff0c;收藏9次。在进行技术学习过程中&#xff0c;由于大部分读者没有经历过一些中大型系统的实际经验&#xff0c;导致无法从服务端⾼并发分布式结构演进之路-----在进行技术学习过程中&a…

低代码技术:简化应用开发,推动数字化转型

在当今快速变化的技术环境中&#xff0c;企业面临着巨大的压力&#xff0c;需要快速响应市场需求并持续推动数字化转型。传统的应用开发方式往往复杂且耗时&#xff0c;开发周期长且需要大量的编程工作。为了应对这些挑战&#xff0c;低代码技术应运而生&#xff0c;为企业提供…

谈谈人工智能在中国:现状与未来展望

随着科技的飞速发展&#xff0c;人工智能&#xff08;AI&#xff09;已经成为推动全球经济和社会发展的关键力量。作为全球科技创新的重要参与者&#xff0c;中国在AI领域取得了令人瞩目的进展&#xff0c;并展现出强大的未来发展潜力。本文将深入分析中国AI的现状&#xff0c;…

XML简介 xml配置文件和properties配置文件对比

目录标题 一、XML简介二、XML配置文件和properties配置文件对比三、XML约束 一、XML简介 XML是EXtensible Markup Language的缩写&#xff0c;翻译过来就是可扩展标记语言。所以很明显&#xff0c;XML和HTML一样都是标记语言&#xff0c;也就是说它们的基本语法都是标签。 可…

windows下安装docker操作步骤

因为最近dockerb被封&#xff0c;下载资源太不方便了&#xff0c;所以还是自己本地安装上docker吧 下载的地址一定不要找错&#xff0c;是这里 https://docs.docker.com/desktop/install/windows-install/ 电脑--“控制面板”--“程序与功能”--开启windows功能 “Hyper-V”…

webSocket的自学案例

问&#xff1a; 请展示一个简单websocket案例&#xff1f; 回答&#xff1a; <!DOCTYPE html><html lang"en"><head><meta charset"UTF-8"><title>简单小例子</title></head><body><input type&quo…

记录游戏高光时刻!4款电脑录屏工具分享

虽然之前也录制过游戏&#xff0c;但是想来还是有不少朋友不知道如何录制一个高清游戏视频&#xff0c;我来和大家聊聊游戏直播和录屏的那些事儿。作为一个游戏主播&#xff0c;我尝试过很多录屏软件&#xff0c;今天就来分享一下我用过的四款录屏软件它们在录制游戏视频时的表…

Win32设备I/O详解

Windows设备 在Windows平台下&#xff0c;设备被定义为能够与之进行通信的任何东西。最常见的 I/O 设备包括&#xff1a;文件、文件流、目录、物理磁盘、卷、控制台缓冲区、磁带驱动器、通信资源、mailslot 和管道等。 平常我们使用的文件&#xff0c;目录都可以称之为设备。…

机床采集网关在汽车智能工厂中的应用及成效-天拓四方

随着工业4.0的浪潮席卷全球&#xff0c;智能化、数字化成为了制造业转型升级的关键词。在这一背景下&#xff0c;机床采集网关以其强大的数据采集、传输和处理能力&#xff0c;为企业的数字化转型提供了强有力的支持。本文将通过一个实际案例&#xff0c;详细介绍机床采集网关在…

数据结构:(LeetCode144)二叉树的前序遍历

给你二叉树的根节点 root &#xff0c;返回它节点值的 前序 遍历。 示例 1&#xff1a; 输入&#xff1a;root [1,null,2,3] 输出&#xff1a;[1,2,3] 解释&#xff1a; 示例 2&#xff1a; 输入&#xff1a;root [1,2,3,4,5,null,8,null,null,6,7,9] 输出&#xff1a;…

CUDA与TensorRT学习二:CUDA编程入门

文章目录 一、理解CUDA的grid和Block1&#xff09;第一个cuda项目 二、理解.cu和.cpp的相互引用及Makefile三、利用CUDA矩阵乘法(matmul)计算、Error Handle 及硬件信息获取1&#xff09;矩阵乘法2&#xff09;Error Handle3&#xff09;硬件信息获取 四、安装Nsight system an…

【APP自动化】Appium 环境搭建

1 基础环境 安装 node.js (1) 安装node.js 安装的是10版本&#xff0c;node-v10.16.0-x64&#xff0c;node.js安装比较简单&#xff0c;直接采用默认选项即可&#xff0c;路径的话&#xff0c;可以自己更改下。 (2) 添加Path环境变量 (3) 验证node.js是否安装成功 可以在CMD…

STM32 IIC

第一块&#xff1a;介绍协议规则&#xff0c;然后用软件模拟的形式来实现协议&#xff0c; 第二块&#xff1a;介绍STM32的IIC外设&#xff0c;然后用硬件来实现协议 因为IIC是同步时序的额&#xff0c;软件模拟协议也非常方便&#xff0c;像我们单片机一样&#xff0c;外挂芯…