Java中常见的线程池以及ThreadPoolTaskExecutor和ThreadPoolExecutor

线程池的基本组成:

线程管理器:用于创建并管理线程池,负责线程池的创建、销毁以及任务的添加。
工作线程:线程池中的线程,负责执行任务,没有任务时处于等待状态。
任务接口:每个任务必须实现的接口。
任务队列:存放没有处理的任务。

Java中常见的线程池

(1)FixedThreadPool:固定大小的线程池,创建时需要指定线程池的大小,当线程池中的线程都在执行任务时,新的任务需要等待。
(2)CachedThreadPool:可以缓存的线程池,可以无限扩大线程池的大小,当线程池中的线程空闲一定时间后,会被回收,当有新的任务需要执行时,又会创建一个新的线程。
(3)SingleThreadPool:只有一个线程的线程池,所有任务按照指定顺序在该线程中执行,如果该线程异常结束,则会创建一个新的线程继续执行任务,保证任务的顺序性。
(4)ScheduledThreadPool:定时执行任务的线程池,支持延迟执行和定时执行两种两种任务,可以用于定时任务、定时检查等场景。
(5)WorkStealingPool:工作窃取线程池,该线程池默认创建的线程数是CPU核心数,线程使用双端队列,当一个线程执行完自己的任务之后,会从其他线程的队列中窃取任务来执行,保证任务的平衡性和执行效率。

ThreadPoolExecutor

这个类是JDK中的线程池类,继承自Executor,Executor顾名思义是专门用来处理多线程相关的一个接口,所有线程相关的类都实现了这个接口,里面有一个execute()方法,用来执行线程,线程池主要提供一个线程队列,队列保存着所有等待状态的线程,避免了创建于销毁线程的额外开销,提高了响应速度。
在这里插入图片描述

线程池接口

ExecutorService为线程池接口通了线程池生命周期方法,继承自Executor接口,ThreadPoolExecutor为线程池实现类,提供了线程池的维护操作等相关方法。,继承自AbstractExecutorService,AbstractExecutorService实现了ExecutorService接口。

工具类:Executors

Executors为线程池工具类,相当于一个工厂类,用来创建合适的线程池,返回ExecutorService类型的线程池,有如下方法:
ExecutorService newFixedThreadPool():创建固定大小的线程池
ExecutorService newCachedThreadPool():缓存线程池,线程池的线程数量不固定,可以根据需求自动的更改数量
ExecutorService newSingleThreadPool():创建单个线程池,线程池里面只有一个线程。
ScheduleedExecutorService newScheduledThreadPool():创建固定大小的线程池,可以延迟或者定时执行任务。

实际应用中一般使用Executors工厂类来创建线程池,Executors工厂实际就是调用的ExecutorPoolService的构造方法,传入默认参数。

ThreadPoolExecutor

例如阿里的规范,是不允许直接使用Executors去创建线程池的,我们可以使用ThreadPoolExecutor 。ThreadPoolExecutor的构造方法如下:

public ThreadPoolExecutor(int corePoolSize,
                              int maximumPoolSize,
                              long keepAliveTime,
                              TimeUnit unit,
                              BlockingQueue<Runnable> workQueue,
                              ThreadFactory threadFactory,
                              RejectedExecutionHandler handler) {}

其中参数的含义是:
corePoolSize:线程池中线程的数量
maximumPoolSize:线程池中的最大线程数量。
keepAliveTime:当线程池线程数量超过corePoolSize时,多余的空闲线程会在多长时间内被销毁。
unit:keepAliveTime的时间单位
workQueue:任务队列,被提交但尚未执行的任务
threadFactory:线程工厂,用于创建线程,一般情况下使用默认的。
handler:拒绝策略,当任务太多来不及处理时,如何拒绝任务。

对于这些参数要有如下理解:
(1)corePoolSize和maximumPoolSize的关系
首先corePoolSize肯定是<=maximumPoolSize。
若当前线程池中线程数<corePoolSize,则每来一个任务就创建一个线程去执行。
若当前线程池中线程数量 >= corePoolSize,会尝试将任务添加到任务队列。如果添加成功,则任务会等待空闲线程将其取出并执行;
若队列已经满了,则当前线程池中线程数 < maximumPoolSize,创建新的线程,这类线程又叫救急线程。
若当前线程池中线程数量 >= maximumPoolSize, 则会采用拒绝策略。

(2)workQueue
参数workQueue是指提交但未执行的任务队列,若当前线程池中线程数量 >= corePoolSize时,就会尝试将任务添加到任务队列里,主要有以下两种任务队列:
SynchronousQueue:直接提交队列。SynchronousQueue没有容量,所以实际上提交的任务不会被添加到任务队列,总是将新任务提交给线程执行,如果没有空闲的线程,则会尝试创建新的线程。如果线程数量已经达到最大值,则会执行拒绝策略。

LinkedBlockingQueue:无界的任务队列。当有新的任务到来时,若系统的线程数小于corePoolSize,线程池就会创建新的线程执行任务;当系统的线程数量等于corePoolSize后,因为是无界的任务队列,总是能成功将任务添加到任务队列中,所以线程数量不再增加。若任务创建的速度远大于任务处理的速度,无界队列会快速增长,知道内存耗尽。

(3)handler
JDK内置了四种拒绝策略:
DiscardOldestPolicy策略:丢弃任务队列中最早添加的任务,并尝试提交当前任务。
CallerRunsPolicy策略:调用主线程执行被拒绝的任务,这提供了一种简单的反馈控制机制,将降低新任务的提交速度。
DiscardPolicy策略:默默丢弃无法处理的任务,不给予任何处理。
AbordPolicy策略:直接抛出异常,阻止系统运行。

ThreadPoolTaskExecutor

ThreadPoolExecutor是属于JDK自带的线程池,实际开发中我们使用更多的是SpringBoot来进行开发,Spring默认也是带了一个线程池ThreadPoolTaskExecutor,ThreadPoolTaskExecutor是对ThreadPoolExecutor进行了封装处理。

@Async

@Async表示当一个方法上标注该类注解时,在被调用的时候就会开启一个新的线程开始异步操作,属于异步处理。
在SpringBoot环境中,要使用@Async注解,我们需要先在启动类上加上@EnableAsync注解。

(1)创建线程池
我们可以用soringBoot默认的线程池,但一般情况下自定义线程池,配置方式有:
使用xml文件配置的方式
使用Java代码结合@Configuration进行配置

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

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

相关文章

B051-cms06-退出 回车登录 登录拦截 记住我 SVN

目录 注销功能实现1.找到退出按钮修改请求路径2.后端删除Session并跳转到登录页面 回车登录功能登陆拦截1.编写登录拦截器2.配置拦截器 记住我后端实现页面实现 取消记住我后端实现页面实现 注销功能实现 1.找到退出按钮修改请求路径 header.jsp <% page language"j…

Linux上安装matlab

首先需要下载文件&#xff0c;微人大正版软件下载里有 然后直接点击&#xff0c;就可以就可以安装&#xff0c;不需要使用挂载命令&#xff0c;然后使用 ./install就可以进行安装了&#xff0c;这里记住是得登录自己的人大邮箱&#xff0c;否则无法激活&#xff0c;然后修改安…

LeetCode·每日一题·2490. 回环句·模拟

作者&#xff1a;小迅 链接&#xff1a;https://leetcode.cn/problems/circular-sentence/solutions/2325227/mo-ni-zhu-shi-chao-ji-xiang-xi-by-xun-ge-x65e/ 来源&#xff1a;力扣&#xff08;LeetCode&#xff09; 著作权归作者所有。商业转载请联系作者获得授权&#xff0…

MySQL 主从复制与读写分离

概念 主从复制与读写分离的意义 企业中的业务通常数据量都比较大&#xff0c;而单台数据库在数据存储、安全性和高并发方面都无法满足实际的需求&#xff0c;所以需要配置多台主从数据服务器&#xff0c;以实现主从复制&#xff0c;增加数据可靠性&#xff0c;读写分离&#x…

不是吧,交换机坏了你还只会这么排查?

又见面了&#xff0c;我的网工朋友 上次给你分享了交换机和路由器的对接上网配置案例&#xff0c;还记得吗&#xff1f; 今天这篇&#xff0c;和你聊聊交换机接口故障。 接口故障这件事&#xff0c;对咱们网工来说其实算是家常便饭了。 工作到现在&#xff0c;你复盘一下&a…

实战:求年月日时间前后遇到的坑和解决方式

这里写目录标题 前言正确实例&#xff1a;错误实例&#xff1a; 需求 前言 这周接到一个时间转换任务需要处理&#xff0c;本来没什么问题&#xff0c;后来完成后发现时间有偏差&#xff0c;又重写了一遍代码&#xff0c;感觉很有记录必要性&#xff0c;希望看过的小伙伴可以避…

计算机网络——数据链路层

序言 问&#xff1a;数据链路层在现在的社会起到什么作用&#xff1f; 答&#xff1a;数据链路层在现在的社会起到关键性作用&#xff0c;比如&#xff1a;数据传输和通信&#xff1b;网络连接和互联互通&#xff1b;错误检测和纠正&#xff1b;媒体访问控制&#xff1b;网络性…

启动一个qemu虚拟机

安装qemu&#xff1a; 编译内核&#xff1a; 编译rootfs&#xff1b; 启动&#xff1a; qemu-system-x86_64 -kernel ./linux-4.14.320/arch/x86_64/boot/bzImage -hda ./busybox-1.36.1/rootfs.img -append "root/dev/sda consolettyS0" -nographic 效果图&am…

【Tensorflow object detection API + 微软NNI】图像分类问题完成自动调参,进一步提升模型准确率!

1. 背景&目标 利用Tensorflow object detection API开发并训练图像分类模型&#xff08;例如&#xff0c;Mobilenetv2等&#xff09;&#xff0c;自己直接手动调参&#xff0c;对于模型的准确率提不到极致&#xff0c;利用微软NNI自动调参工具进行调参&#xff0c;进一步提…

Cisco Catalyst 8000 Series Edge Platforms, IOS XE Release Dublin-17.11.01a ED

Cisco Catalyst 8000 Series Edge Platforms, IOS XE Release Dublin-17.11.01a ED Cisco Catalyst 8000 边缘平台系列 请访问原文链接&#xff1a;https://sysin.org/blog/cisco-catalyst-8000/&#xff0c;查看最新版。原创作品&#xff0c;转载请保留出处。 作者主页&…

国企一面会问什么?

前言&#xff1a; \textcolor{Green}{前言&#xff1a;} 前言&#xff1a; &#x1f49e;快秋招了&#xff0c;那么这个专栏就专门来记录一下&#xff0c;同时呢整理一下常见面试题 &#x1f49e;部分题目来自自己的面试题&#xff0c;部分题目来自网络整理 国企注重的和私企会…

AI实战营第二期 第七节 《语义分割与MMSegmentation》——笔记8

文章目录 摘要主要特性 案例什么是语义分割应用&#xff1a;无人驾驶汽车应用&#xff1a;人像分割应用&#xff1a;智能遥感应用 : 医疗影像分析 三种分割的区别语义分割的基本思路按颜色分割逐像素份分类全卷积网络 Fully Convolutional Network 2015存在问题 基于多层级特征…

多元回归预测 | Matlab基于灰狼算法(GWO)优化混合核极限学习机HKELM回归预测, GWO-HKELM数据回归预测,多变量输入模型

文章目录 效果一览文章概述部分源码参考资料效果一览 文章概述 多元回归预测 | Matlab基于灰狼算法(GWO)优化混合核极限学习机HKELM回归预测, GWO-HKELM数据回归预测,多变量输入模型 评价指标包括:MAE、RMSE和R2等,代码质量极高,方便学习和替换数据。要求2018版本及以上。 …

[游戏开发][Unity]出包真机运行花屏(已解决)

花屏真机截屏 原因 原因是启动项目时的第一个场景没有相机是 Skybox或者SolidColor模式&#xff0c;我的启动场景只有一个UI相机&#xff0c;且Clear Flags是DepthOnly 解释&#xff1a; https://blog.csdn.net/yanchezuo/article/details/79002318

三、1如何运用设计原则之SOLID原则写出高质量代码?

你好我是程序员雪球。接下来我们学习一些经典的设计原则。其中包括SOLID&#xff0c;KISS&#xff0c;YAGNI&#xff0c;DRY&#xff0c;LOD等。其实这些设计原则从字面意思理解并不难。但是“看懂”和“会用”是两回事&#xff0c;而“用好”就难上加难了。 先来了解SOLID原则…

(css)el-image图片完整显示,不拉伸收缩

(css)el-image图片完整显示&#xff0c;不拉伸收缩 <el-imagefit"contain" //重要设置src"../../../../1.png"altclass"chenguo_img_img" />

自动驾驶货车编队行驶-车辆通讯应用层数据交互要求

1 范围 本文件规定了合作式自动驾驶货车编队行驶时车辆通信应用层数据交互的通信系统架构、通用要求、 数据交互要求、消息层数据集定义等。本文件仅涉及编队成员内部进行编队控制及成员管理相关的车-车通 信交互&#xff0c;不涉及编队与其他实体&#xff08;云平台、路侧单元…

spring cloud 之 gateway

网关介绍 在微服务架构体系中&#xff0c;一个系统会被拆分为很多个微服务&#xff0c;那么作为客户端要如何去调用这么多的微服务呢&#xff1f;如果没有网关的存在&#xff0c;我们只能在客户端记录每个微服务的地址&#xff0c;然后分别调用&#xff0c;当然这样是不现实的…

高性能消息中间件 RabbitMQ

一、RabbitMQ概念 1.1 MQ是什么 消息队列 MQ全称Message Queue&#xff08;消息队列&#xff09;&#xff0c;是在消息的传输过程中保存消息的容器。多用于系统之间的异步通信。 同步通信相当于两个人当面对话&#xff0c;你一言我一语。必须及时回复&#xff1a; 异步通信相…

基于Arduino UNO的循迹小车

目录 1.analogWrite函数的使用 2.红外循迹模块介绍 3.循迹小车代码实现 4.实物示例 1.analogWrite函数的使用 用analogWrite来替换digitalWrite 说明 将一个模拟数值写进Arduino引脚。这个操作可以用来控制LED的亮度, 或者控制电机的转速. 在Arduino UNO控制器中&#…