Java线程池,看这一篇足够

news2024/12/25 12:50:34

目录一览

  • Java线程池
    • 1. Executors提供6个线程池快捷创建方式
    • 2. ThreadPoolExecutor的7大参数
    • 3. 自定义线程池

Java线程池

上一篇《@Async注解的注意事项》说到@Async注解要配合自定义线程池一起使用,这一节说下Java的线程池。

1. Executors提供6个线程池快捷创建方式

    public static void main(String[] args) {
        // 定长线程池,核心线程数和最大线程数一致
        ExecutorService executorService = Executors.newFixedThreadPool(10);
        // 缓存线程池,核心线程数为0,最大线程数Integer最大值,线程存活时间超长
        ExecutorService executorService1 = Executors.newCachedThreadPool();
        // 定时线程池,可以设置执行时间
        ScheduledExecutorService scheduledExecutorService = Executors.newScheduledThreadPool(10);
        // 单线程线程池,核心线程和最大线程数都为1
        ExecutorService executorService2 = Executors.newSingleThreadExecutor();
        // 核心线程数为1的定时线程池,可以执行定时任务
        ScheduledExecutorService scheduledExecutorService1 = Executors.newSingleThreadScheduledExecutor();
        // 窃取线程池,并行执行线程,依赖cpu个数
        ExecutorService executorService3 = Executors.newWorkStealingPool(3);
    }

通过调试依次看下各个线程池的实际参数

newFixedThreadPool,定长线程池

在这里插入图片描述

可见,corePoolSize和maxinumPoolSize数是一样的,说明线程不会销毁,且不会动态扩容。灵活性较差

newCachedThreadPool,缓存线程池

在这里插入图片描述

corePoolSize为0,maxinumPoolSize为max integer,重点是keepAliveTime为600亿毫秒,线程一旦创建几乎不会销毁,容易造成OOM。

newScheduledThreadPool,定时线程池

在这里插入图片描述

maxinumPoolSize为max integer,可能造成OOM。主要特点是创建的ScheduledThreadPoolExecutor实现了ScheduledExecutorService接口,其中的schedule等方法可以设置定时执行任务。

在这里插入图片描述

newSingleThreadExecutor,单线程线程池

在这里插入图片描述

corePoolSize和maxinumPoolSize都为1,说明单个线程执行任务,未执行的任务只能堆叠在workQueue。

newSingleThreadScheduledExecutor,单线程定时线程池

在这里插入图片描述

事实上就是newScheduledThreadPool,只是corePoolSize设置为1

在这里插入图片描述

newWorkStealingPool,窃取线程池

在这里插入图片描述

这个线程池比较特殊,它是java8才提出来的,不是通过ThreadPoolExecutor创建,没有corePoolSize等参数。且线程是并行进行的,即依赖处理器进行。

我觉得下面这篇文章对我有帮助,可以阅读一下

WorkStealingPool的使用简析

以上就是通过Executors创建的6种线程池

2. ThreadPoolExecutor的7大参数

通过Executors创建的6种线程池,除了java8提出的newWorkStealingPool,其他都是直接或者间接(子类)创建

ThreadPoolExecutor类实现的。

在这里插入图片描述

ThreadPoolExecutor主要有7大参数

在这里插入图片描述

  • corePoolSize,核心线程数,线程池默认线程数,线程池创建完成时,会初始化的线程数量,当有任务进来时,通过调度线程执行任务。

  • maxinumPoolSize,最大线程数,最大线程数必须大于或等于核心线程数,核心线程正在执行任务,而有新任务进来,且当下线程数量未达到最大线程数时,会新建线程放进线程池,再用新线程执行任务。

  • keepAliveTime,存活时间,除开核心线程外的线程,也就是大于核心线程数的部分线程,如果没有任务调度该线程执行,当该线程的空闲时间达到keepALiveTime值时,会被销毁。

  • unit,时间单位,keepAliveTime的单位,一般为毫秒

  • workQueue,工作队列,也称为等待队列,任务调用时先进入工作队列,然后等待空闲线程调度。

  • threadFactory,线程工厂,指定创建线程的方式,通过线程工厂创建和销毁线程,一般使用 Executors.defaultThreadFactory() 足够,不用自定义创建该工厂类。

  • handler,拒绝策略,该类主要针对当工作队列满了之后,新的任务进来,拒绝存放在工作队列,执行的操作。其中rejectedExecution方法就是拒绝的处理方法。

    ThreadPoolExecutor提供了默认四种拒绝策略。(如果不理解可以看下源码,很简单的逻辑)

    • CallerRunsPolicy,从哪来,往哪走,由提交执行任务。
    • AbortPolicy,直接报异常
    • DiscardPolicy,什么都不做,rejectedExecution这个方法直接留空,哈哈
    • DiscardOldestPolicy,workQueue最后的任务直接踢掉,然后插入本任务

3. 自定义线程池

在阿里开发手册中明令禁止使用Executors创建线程池,通过以上第一点介绍的6种线程池可以看出,Executors提供的线程池中有些maxinumPoolSize设置为max integer,或者workQueue的容量设置为max integer(如newFixedThreadPool和newSingleThreadExecutor中,workQueue使用LinkedBlockingQueue,其size为Integer.MAX_VALUE),这存在内存溢出风险。

因而在实际开发中,最好自定义线程池。只需要实例化ThreadPoolExecutor类即可,所以自定义线程池实质上就是配置好上述第二点中的7大参数。

    public ThreadPoolExecutor myThreadExecutor(){
        ThreadPoolExecutor threadPoolExecutor = new ThreadPoolExecutor(
                10,
                20,
                60,
                TimeUnit.SECONDS,
                new LinkedBlockingQueue<>(100),
                Executors.defaultThreadFactory(),
                new ThreadPoolExecutor.AbortPolicy()
        );
        return threadPoolExecutor;
    }

最后,@Async配合自定义线程池使用,可以看我上篇文章《@Async注解的注意事项》

至此,全篇结束

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

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

相关文章

基于springboot+vue的小徐影城管理系统(前后端分离)

博主主页&#xff1a;猫头鹰源码 博主简介&#xff1a;Java领域优质创作者、CSDN博客专家、公司架构师、全网粉丝5万、专注Java技术领域和毕业设计项目实战 主要内容&#xff1a;毕业设计(Javaweb项目|小程序等)、简历模板、学习资料、面试题库、技术咨询 文末联系获取 项目介绍…

一个处理Range List的面试题解法

大纲 题目解法Rangeaddremove ToolsRangeListaddremove 代码 最近看到一个比较有意思的面试题。题目不算难&#xff0c;但是想把效率优化做好&#xff0c;也没那么容易。 我们先看下题目 题目 // Task: Implement a class named RangeList // A pair of integers define a ra…

K8S搭建(centos)三、安装Docker

天行健&#xff0c;君子以自强不息&#xff1b;地势坤&#xff0c;君子以厚德载物。 每个人都有惰性&#xff0c;但不断学习是好好生活的根本&#xff0c;共勉&#xff01; 文章均为学习整理笔记&#xff0c;分享记录为主&#xff0c;如有错误请指正&#xff0c;共同学习进步。…

完美调试android-goldfish(linux kernel) aarch64的方法

环境要求 Mac m1Mac m1 中 虚拟机安装aarch64 ubuntu22.02Mac m1安装OrbStack&#xff0c;并在其中安装 ubuntu20.04&#xff08;x86_64&#xff09; 构建文件系统 在虚拟机 aarch64 ubuntu22.02中构建 安装必要的库 sudo apt-get install libncurses5-dev build-essenti…

工业空调协议转BACnet网关BA108

随着通讯技术和控制技术的发展&#xff0c;为了实现楼宇的高效、智能化管理&#xff0c;集中监控管理已成为楼宇智能管理发展的必然趋势。在此背景下&#xff0c;高性能的楼宇暖通数据传输解决方案——协议转换网关应运而生&#xff0c;广泛应用于楼宇自控和暖通空调系统应用中…

RK3399平台开发系列讲解(USB篇)USB协议层数据格式

🚀返回专栏总目录 文章目录 一、USB 资料二、协议层2.1、字节/位传输顺序2.2、SOP起始包2.3、SYNC同步域2.4、EOP 结束包(End of Packet)2.5、Packet内容2.5.1、PID:2.5.2、地址:2.5.3、帧号:2.5.4、数据域:

Linux——理解文件系统

目录 1、inode 2、硬链接、软链接 理解硬链接 软链接 3、静态库、动态库 静态库与动态库 生成静态库 生成动态库 使用动态库 运行动态库 使用外部库 库文件名称和引入库的名称 1、inode 使用ls -l命令不仅显示出了文件名&#xff0c;也可以显示出文件元数据 一行…

k8s 容器 java 应用内存限制不生效

一 k8s java 应用内存限制不生效 回顾&#xff1a;Linux杂谈之java命令 namespace负责资源隔离 cgroups负责资源限制 容器JVM最佳实践 Metaspace 是 非 Heap 内存 管理空间,那么 Heap 就是操作空间 JVM内存模型简介 隔离&#xff1a; 两个进程完全隔离感知&#xff1…

【STM32】STM32F4中USB的CDC虚拟串口(VCP)使用方法

文章目录 一、前言二、STM32CubeMX生成代码2.1 选择芯片2.2 配置相关模式2.3 设置时钟频率2.4 生成代码2.5 编译并下载代码2.6 结果2.7 问题 三、回环测试3.1 打开工程3.2 添加回环代码3.3 编译烧录并测试 四、出现问题和解决方法4.1 烧录总是要自己插拔USB4.2 自己生成的工程没…

141:vue+leaflet 利用高德逆地理编码,点击地图标记marker,popup地址信息

第141个 点击查看专栏目录 本示例的目的是介绍演示如何在vue+leaflet中利用高德逆地理编码,点击地图标记marker,popup地址信息 。主要利用高德地图的api将坐标转化为地址,然后在点击的位置,弹出弹窗,在里面显示出地址信息。 直接复制下面的 vue+leaflet源代码,操作2分钟…

14、Kafka ------ kafka 核心API 之 流API(就是把一个主题的消息 导流 到另一个主题里面去)

目录 kafka 核心API 之 流APIKafka流API的作用&#xff1a;流API的核心API&#xff1a;使用流API编程的大致步骤如下&#xff1a;代码演示 流API 用法MessageStream 流API 代码演示消息从 test1主题 导流到 test2主题演示使用匿名内部类对消息进行处理Topology 拓扑结构 讲解 代…

【AIGC】CLIP

CLIP的基本原理 对比学习&#xff1a; Clip使用对比学习来训练模型。对比学习的目标是通过将正样本&#xff08;相似的图像和文本对&#xff09;与负样本&#xff08;不相似的图像和文本对&#xff09;进行比较&#xff0c;从而使模型学会区分不同样本之间的差异。这有助于模型…

社区分享|百果园选择DataEase搭档蜜蜂微搭实现企业数据应用一体化

百果园&#xff0c;全称为深圳百果园实业&#xff08;集团&#xff09;股份有限公司&#xff0c;2001年12月成立于深圳&#xff0c;2002年开出中国第一家水果专卖店。截至2022年11月&#xff0c;百果园全国门店数量超过5600家&#xff0c;遍布全国140多个城市&#xff0c;消费会…

TensorRT英伟达官方示例解析(二)

系列文章目录 TensorRT英伟达官方示例解析&#xff08;一&#xff09; TensorRT英伟达官方示例解析&#xff08;二&#xff09; 文章目录 系列文章目录前言一、03-BuildEngineByTensorRTAPI1.1 建立 Logger&#xff08;日志记录器&#xff09;1.2 Builder 引擎构建器1.3 Netwo…

【SGX系列教程】(一)Intel-SGX SDK在ubuntu22.04下安装全流程

文章目录 一.概述1.1 SGX三大组件1.2 SGXDataCenterAttestationPrimitives 二.安装流程2.1 检查服务器是否支持SGX2.2 sgx硬件/软件开启方法2.3 sgx dirver驱动安装&#xff1b;2.3.1 linux-sgx-driver驱动程序2.3.2 Intel SGX Support in the Linux Kernel&#xff08;linux内…

【开源】基于JAVA的图书管理系统

目录 一、 系统介绍二、 功能模块2.1 登录注册模块2.1 图书馆模块2.2 图书类型模块2.3 图书模块2.4 图书借阅模块2.5 公告模块 三、 源码解析3.1 图书馆模块设计3.2 图书类型模块设计3.3 图书模块设计3.4 图书借阅模块设计3.5 公告模块设计 四、 免责说明 一、 系统介绍 图书管…

AnimatedDrawings:让绘图动起来

老样子&#xff0c;先上图片和官网。这个项目是让绘制的动画图片动起来&#xff0c;还能绑定人体的运动进行行为定制。 快速开始 1. 下载代码并进入文件夹&#xff0c;启动一键安装 git clone https://github.com/facebookresearch/AnimatedDrawings.gitcd AnimatedDrawingspip…

4小时精通MyBatisPlus框架

目录 1.介绍 2.快速入门 2.1.环境准备 2.2.快速开始 2.2.1引入依赖 2.2.2.定义Mapper ​编辑 2.2.3.测试 2.3.常见注解 ​编辑 2.3.1.TableName 2.3.2.TableId 2.3.3.TableField 2.4.常见配置 3.核心功能 3.1.条件构造器 3.1.1.QueryWrapper 3.1.2.UpdateWra…

SpringBoot3集成Zookeeper

标签&#xff1a;Zookeeper3.8 &#xff0c;Curator5.5&#xff1b; 一、简介 ZooKeeper是一个集中的服务&#xff0c;用于维护配置信息、命名、提供分布式同步、提供组服务。分布式应用程序以某种形式使用所有这些类型的服务。 二、环境搭建 1、修改配置文件 # 1、拷贝一份…

不合格机器人工程讲师再读《悉达多》-2024-

一次又一次失败的经历&#xff0c;让我对经典书籍的认同感越来越多&#xff0c;越来越觉得原来的自己是多么多么的无知和愚昧。 ----zhangrelay 唯物也好&#xff0c;唯心也罢&#xff0c;我们都要先热爱这个世界&#xff0c;然后才能在其中找到自己所热爱的事业。 ----zh…