当前位置: 首页 > news >正文

ThreadPoolExecutor管理异步线程笔记

为什么使用线程池?

  • 线程的创建和销毁都需要不小的系统开销,不加以控制管理容易发生OOM错误。
  • 避免线程并发抢占系统资源导致系统阻塞。
  • 具备一定的线程管理能力(数量、存活时间,任务管理)
new ThreadPoolExecutor(int corePoolSize,int maximumPoolSize,long keepAliveTime,TimeUnit unit,BlockingQueue<Runnable> workQueue,ThreadFactory threadFactory) ;

参数说明

  • corePoolSize: 线程池中的线程数量
  • maximumPoolSize: 线程池中的最大线程数量
  • keepAliveTime: 当线程池线程数量超过corePoolsize时,多余的空闲线程的存活时间,即超过corePoolSize的空闲线程,在keepAliveTime时间内会被销毁
  • TimeUnit unit: keepAliveTime的单位
  • BlockingQueue<Runnable> workQueue: 任务队列,管理被提交但尚未被执行的任务
  • ThreadFactory threadFactory: 线程工厂,用于创建线程
  • RejectedExecutionHandler handler: 拒绝策略。当任务太多来不及处理时,如何拒绝任务

BlockingQueue的几种形式

  • SynchronousQueue:这个队列接收到任务的时候,会直接提交给线程处理,而不保留它,如果所有线程都在工作怎么办?那就新建一个线程来处理这个任务!所以为了保证不出现<线程数达到了maximumPoolSize而不能新建线程>的错误,使用这个类型队列的时候,maximumPoolSize一般指定成Integer.MAX_VALUE,即无限大(但是这样就容易成OOM,因为Spring的工具类Executors创建线程池的底层也是使用MAX_VALUE所以并不是很推荐)。

  • LinkedBlockingQueue:这个队列接收到任务的时候,如果当前线程数小于核心线程数,则新建线程(核心线程)处理任务;如果当前线程数等于核心线程数,则进入队列等待。由于这个队列没有最大值限制,即所有超过核心线程数的任务都将被添加到队列中,这也就导致了maximumPoolSize的设定失效,因为总线程数永远不会超过corePoolSize。(该方式需要协调好任务处理时间,否则容易造成任务数量过多,最差的情况会耗尽系统资源)

  • ArrayBlockingQueue:可以限定队列的长度,接收到任务的时候,如果没有达到corePoolSize的值,则新建线程(核心线程)执行任务,如果达到了,则入队等候,如果队列已满,则新建线程(非核心线程)执行任务,又如果总线程数到了maximumPoolSize,并且队列也满了,则发生错误。

  • DelayQueue:队列内元素必须实现Delayed接口,这就意味着你传进去的任务必须先实现Delayed接口。这个队列接收到任务时,首先先入队,只有达到了指定的延时时间,才会执行任务。

示例Demo

    @Testpublic void testExecutor() {ThreadPoolExecutor pool = new ThreadPoolExecutor(50, 50, 60, TimeUnit.SECONDS, new LinkedBlockingDeque<>(),new NamedThreadFactory("CustomerThreadName01") // 自定义线程池名称);// 默认Runnablefor (int i = 0; i < 10; i++) {pool.execute(new Runnable() {@Overridepublic void run() {// doSomeThing}});}// 自定义Runnablefor (int i = 0; i < 10; i++) {pool.execute(new MyRunnable("线程" + i, array[i]));}}

这里使用自定义线程池和自定义MyRunnable的目的是为了当线程出现异常的时候,通过日志可以更具自定线程池的名称和自定义Runnable的名称知道是哪个线程的池发生的异常,所以一般推荐不同的业务使用不同线程池的时候,便于线程异常的时候追查。

package com.lg.demo.thread.factory;import java.util.concurrent.ThreadFactory;
import java.util.concurrent.atomic.AtomicInteger;/*** @Description: 自定义线程池名称* @Author: GE LIANG* @Date: 2023/1/30 15:11*/
public class NamedThreadFactory implements ThreadFactory {private static final AtomicInteger poolNumber = new AtomicInteger(1);private final ThreadGroup group;private final AtomicInteger threadNumber = new AtomicInteger(1);private final String namePrefix;public NamedThreadFactory(String name){SecurityManager s = System.getSecurityManager();group = (s != null) ? s.getThreadGroup() : Thread.currentThread().getThreadGroup();if (null == name || name.isEmpty()){name = "pool";}namePrefix = name + "-" + poolNumber.getAndIncrement() + "-thread-";}@Overridepublic Thread newThread(Runnable r){Thread t = new Thread(group, r, namePrefix + threadNumber.getAndIncrement(), 0);if (t.isDaemon()){t.setDaemon(false);}if (t.getPriority() != Thread.NORM_PRIORITY){t.setPriority(Thread.NORM_PRIORITY);}return t;}
}
package com.lg.demo.thread.funnable;import lombok.Data;/*** @Description: 可自定义Runnable* @Author: GE LIANG* @Date: 2023/1/30 15:27*/
public class MyRunnable implements Runnable {public String name;public Integer index;public MyRunnable(String name, Integer index) {this.name = name;this.index = index;}@Overridepublic void run() {System.out.println(name + ">>>" + index);}public String getName() {return name;}public void setName(String name) {this.name = name;}public Integer getIndex() {return index;}public void setIndex(Integer index) {this.index = index;}
}

引用

《阿里巴巴Java开发规范》
《Java常用四大线程池用法以及ThreadPoolExecutor详解》

相关文章:

ThreadPoolExecutor管理异步线程笔记

为什么使用线程池&#xff1f; 线程的创建和销毁都需要不小的系统开销&#xff0c;不加以控制管理容易发生OOM错误。避免线程并发抢占系统资源导致系统阻塞。具备一定的线程管理能力&#xff08;数量、存活时间&#xff0c;任务管理&#xff09; new ThreadPoolExecutor(int …...

MotoSimEG-VRC教程:动态输送带创建以及示教编程与仿真运行

目录 任务描述 简易输送带外部设备创建 输送带模型添加与配置 工件安装到输送带 输送带输送工件程序编写与仿真运行 任务描述 在MotoSimEG-VRC中创建1条输送带&#xff0c;并且能够实现将工件从输送带起始点位置处输送到结束点位置处。 简易输送带外部设备创建 在MotoS…...

PyTorch 并行训练 DistributedDataParallel完整代码示例

使用大型数据集训练大型深度神经网络 (DNN) 的问题是深度学习领域的主要挑战。 随着 DNN 和数据集规模的增加&#xff0c;训练这些模型的计算和内存需求也会增加。 这使得在计算资源有限的单台机器上训练这些模型变得困难甚至不可能。 使用大型数据集训练大型 DNN 的一些主要挑…...

Golang实现ttl机制保存内存数据

ttl(time-to-live) 数据存活时间&#xff0c;我们这里指数据在内存中保存一段时间&#xff0c;超过期限则不能被读取到&#xff0c;与Redis的ttl机制类似。本文仅实现ttl部分&#xff0c;不考虑序列化和反序列化。 获取当前时间 涉及时间计算&#xff0c;这里首先介绍如何获取…...

js中数字运算结果与预期不一致的问题和解决方案

本文主要是和大家聊聊关于js中经常出现数字运算结果与预期结果不一致的问题&#xff0c;与及解决该问题的的方案。 一、问题现象 如&#xff1a;0.1 0.2的预期结果是0.3&#xff0c;但是在js中得到的计算结果却是0.30000000000000004&#xff0c;如下图所示 如&#xff1a;0…...

C++ Primer Plus 学习笔记(一)——基本类型

字节与字符 计算机内存的基本单位是位&#xff08;bit&#xff09;&#xff0c;字节&#xff08;byte&#xff09;通常指的是8位的内存单元&#xff0c;从这个意义上来说&#xff0c;字节指的就是描述计算机内存量的度量单位。 C对字节的定义则有些不同&#xff0c;C字节由至…...

ChatGpt与Google 谁能给出最好的回答

ChatGPT由于其先进的会话和技术功能而越来越受欢迎。你可以问聊天机器人任何你想问的问题&#xff0c;它会在几秒钟内输出答案。虽然它不是一个搜索引擎&#xff0c;你应该使用ChatGPT作为你的信息来源而不是谷歌&#xff0c;百度吗? 我们来根据国外的一场测试来看一下 ChatG…...

【Redis】一、CentOS64 安装 Redis

1.下载redis https://download.redis.io/releases/2.将 redis 安装包拷贝到 /opt/ 目录 最好自己创建一个文件夹 3.解压 tar -zvxf redis-6.2.1.tar.gz4. 安装gcc yum install gcc5. 进入目录 cd /opt/redis/redis-6.2.1/6. 编译 make7.执行 make install 进行安装 8. …...

Redis底层原理(持久化+分布式锁)

Redis底层原理 持久化 Redis虽然是个内存数据库&#xff0c;但是Redis支持RDB和AOF &#xff08;Redis Database Backup file&#xff08;Redis数据备份文件&#xff09;&#xff0c;也被叫做Redis数据快照。简单来说就是把内存中的所有数据都记录到磁盘中 &#xff1b;Appen…...

Spring Cloud Nacos实战(八) - Nacos集群配置

Nacos集群配置 更改Nacos启动命令配置原理 我们现在知道&#xff0c;想要启动Naocs只需要启动startup.sh命令即可&#xff0c;但是如果启动3个Nacos那&#xff1f;所以如果我们需要启动多个Nacos&#xff0c;其实Nacos本身默认启动就是集群模式。 注意点&#xff1a;如果是l…...

什么是低代码-甲骨文对低代码的定义

什么是低代码平台&#xff1f;低代码阶段使用简化的界面&#xff0c;允许开发人员构建应用程序和软件 既用户友好又响应迅速。而不是编写几行复杂的代码和语言结构&#xff0c; 您可以快速轻松地利用低代码来构建具有用户界面的整体应用程序&#xff0c; 组合和信息。低代码可以…...

shell编程之循环语句

typora-copy-images-to: pictures typora-root-url: …\pictures 文章目录typora-copy-images-to: pictures typora-root-url: ..\..\pictures一、for循环语句1. for循环语法结构㈠ 列表循环㈡ 不带列表循环㈢ 类C风格的for循环2. 应用案例㈠ 脚本计算1-100奇数和① 思路② 落地…...

神经动力学-第一章-神经动力学基础-神经系统的元素

神经元和数学 本章的主要目的是介绍神经科学的几个基本概念,尤其是动作电位、突触后电位、触发阈值、不应期和适应性。基于这些概念,建立了神经元动力学的初步模型,这个简单的模型(漏积分-火模型)将作为本书主题——广义积分-火模型的起点和参考,在第二部分和第三部分进…...

【力扣-LeetCode】64. 最小路径和 C++题解

64. 最小路径和难度中等1430收藏分享切换为英文接收动态反馈给定一个包含非负整数的 m x n 网格 grid &#xff0c;请找出一条从左上角到右下角的路径&#xff0c;使得路径上的数字总和为最小。说明&#xff1a;每次只能向下或者向右移动一步。示例 1&#xff1a;输入&#xff…...

Mysql数据库事务

数据库事务 数据库事务由一组sql语句组成。 所有sql语句执行成功则事务整体成功&#xff1b;任一条sql语句失败则事务整体失败&#xff0c;数据恢复到事务之前的状态。 Mysql 事务操作 开始事务 start transaction;- 或 begin;事务开始后&#xff0c;对数据的增删改操作不…...

【opencv源码解析0.3】调试opencv源码的两种方式

调试opencv源码的两种方式 上两篇我们分别讲了如何配置opencv环境&#xff0c;以及如何编译opencv源码方便我们阅读。但我们还是无法调试我们的代码&#xff0c;无法以我们的程序作为入口来一步一步单点调试看opencv是如何执行的。 【opencv源码解析0.1】VS如何优雅的配置ope…...

Xcode Archives打包上传 / 导出ipa 发布至TestFlight

Xcode自带的Archives工具可以傻瓜式上传到App Store Connect分发这里以分发到TestFlight为例进行操作。 环境&#xff1a;Xcode 14 一&#xff1a;Archives打包 选择Xcode菜单栏的Product&#xff0c;Archives选项&#xff0c;需要等待编译完成&#xff0c;进入如下界面&…...

RNN GRU模型 LSTM模型图解笔记

RNN模型图解引用RNN模型GRULSTM深度RNN双向循环神经网络引用 动手学深度学习v2–李沐 LSTM长短期记忆网络3D模型–B站up梗直哥丶 RNN模型 加入了一个隐变量&#xff08;状态)&#xff0c;隐变量由上个隐变量和上一个输入而更新&#xff0c;这样模型就可以达到具有短期记忆的效…...

西电_数字信号处理二_学习笔记

文章目录【 第1章 离散随机信号 】【 第2章 维纳滤波 】【 第3章 卡尔曼滤波 】【 第4章 自适应滤波 】【 第5章 功率谱估计 】这是博主2022秋季所学数字信号处理二的思维导图&#xff08;软件是幕布&#xff09;&#xff0c;供大家参考&#xff0c;如内容上有不妥之处&#xf…...

[ vulhub漏洞复现篇 ] Drupal 远程代码执行漏洞(CVE-2018-7602)

&#x1f36c; 博主介绍 &#x1f468;‍&#x1f393; 博主介绍&#xff1a;大家好&#xff0c;我是 _PowerShell &#xff0c;很高兴认识大家~ ✨主攻领域&#xff1a;【渗透领域】【数据通信】 【通讯安全】 【web安全】【面试分析】 &#x1f389;点赞➕评论➕收藏 养成习…...

(LeetCode 每日一题) 3442. 奇偶频次间的最大差值 I (哈希、字符串)

题目&#xff1a;3442. 奇偶频次间的最大差值 I 思路 &#xff1a;哈希&#xff0c;时间复杂度0(n)。 用哈希表来记录每个字符串中字符的分布情况&#xff0c;哈希表这里用数组即可实现。 C版本&#xff1a; class Solution { public:int maxDifference(string s) {int a[26]…...

深入浅出Asp.Net Core MVC应用开发系列-AspNetCore中的日志记录

ASP.NET Core 是一个跨平台的开源框架&#xff0c;用于在 Windows、macOS 或 Linux 上生成基于云的新式 Web 应用。 ASP.NET Core 中的日志记录 .NET 通过 ILogger API 支持高性能结构化日志记录&#xff0c;以帮助监视应用程序行为和诊断问题。 可以通过配置不同的记录提供程…...

day52 ResNet18 CBAM

在深度学习的旅程中&#xff0c;我们不断探索如何提升模型的性能。今天&#xff0c;我将分享我在 ResNet18 模型中插入 CBAM&#xff08;Convolutional Block Attention Module&#xff09;模块&#xff0c;并采用分阶段微调策略的实践过程。通过这个过程&#xff0c;我不仅提升…...

1688商品列表API与其他数据源的对接思路

将1688商品列表API与其他数据源对接时&#xff0c;需结合业务场景设计数据流转链路&#xff0c;重点关注数据格式兼容性、接口调用频率控制及数据一致性维护。以下是具体对接思路及关键技术点&#xff1a; 一、核心对接场景与目标 商品数据同步 场景&#xff1a;将1688商品信息…...

CentOS下的分布式内存计算Spark环境部署

一、Spark 核心架构与应用场景 1.1 分布式计算引擎的核心优势 Spark 是基于内存的分布式计算框架&#xff0c;相比 MapReduce 具有以下核心优势&#xff1a; 内存计算&#xff1a;数据可常驻内存&#xff0c;迭代计算性能提升 10-100 倍&#xff08;文档段落&#xff1a;3-79…...

Qwen3-Embedding-0.6B深度解析:多语言语义检索的轻量级利器

第一章 引言&#xff1a;语义表示的新时代挑战与Qwen3的破局之路 1.1 文本嵌入的核心价值与技术演进 在人工智能领域&#xff0c;文本嵌入技术如同连接自然语言与机器理解的“神经突触”——它将人类语言转化为计算机可计算的语义向量&#xff0c;支撑着搜索引擎、推荐系统、…...

Cinnamon修改面板小工具图标

Cinnamon开始菜单-CSDN博客 设置模块都是做好的&#xff0c;比GNOME简单得多&#xff01; 在 applet.js 里增加 const Settings imports.ui.settings;this.settings new Settings.AppletSettings(this, HTYMenusonichy, instance_id); this.settings.bind(menu-icon, menu…...

【生成模型】视频生成论文调研

工作清单 上游应用方向&#xff1a;控制、速度、时长、高动态、多主体驱动 类型工作基础模型WAN / WAN-VACE / HunyuanVideo控制条件轨迹控制ATI~镜头控制ReCamMaster~多主体驱动Phantom~音频驱动Let Them Talk: Audio-Driven Multi-Person Conversational Video Generation速…...

在QWebEngineView上实现鼠标、触摸等事件捕获的解决方案

这个问题我看其他博主也写了&#xff0c;要么要会员、要么写的乱七八糟。这里我整理一下&#xff0c;把问题说清楚并且给出代码&#xff0c;拿去用就行&#xff0c;照着葫芦画瓢。 问题 在继承QWebEngineView后&#xff0c;重写mousePressEvent或event函数无法捕获鼠标按下事…...

CVE-2020-17519源码分析与漏洞复现(Flink 任意文件读取)

漏洞概览 漏洞名称&#xff1a;Apache Flink REST API 任意文件读取漏洞CVE编号&#xff1a;CVE-2020-17519CVSS评分&#xff1a;7.5影响版本&#xff1a;Apache Flink 1.11.0、1.11.1、1.11.2修复版本&#xff1a;≥ 1.11.3 或 ≥ 1.12.0漏洞类型&#xff1a;路径遍历&#x…...