记手动粗浅管理多线程的工具类

news/2024/12/28 12:57:45/文章来源:https://www.cnblogs.com/mr-tomato/p/18637400

首先新建一个线程池管理工具类ThreadPoolManagerUtil

import lombok.extern.slf4j.Slf4j;import java.util.concurrent.ArrayBlockingQueue;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ThreadFactory;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicInteger;/*** 线程池管理工具类* 提供单例线程池和多实例线程池的管理功能,支持动态配置、线程池状态监控、优雅关闭等操作。*/
@Slf4j
public class ThreadPoolManagerUtil {/*** 单例线程池实例(全局通用线程池)*/private static volatile ThreadPoolExecutor singleThreadPoolExecutor;/*** 多线程池实例集合*/private static final ConcurrentHashMap<String, ThreadPoolExecutor> threadPools = new ConcurrentHashMap<>();/*** 线程池默认核心线程数*/private static final int DEFAULT_CORE_POOL_SIZE = 4;/*** 线程池默认最大线程数*/private static final int DEFAULT_MAXIMUM_POOL_SIZE = 8;/*** 线程池默认空闲线程存活时间*/private static final long DEFAULT_KEEP_ALIVE_TIME = 60L;/*** 线程池默认阻塞队列容量*/private static final int DEFAULT_QUEUE_CAPACITY = 100;/*** 私有构造方法,避免外部实例化*/private ThreadPoolManagerUtil() {}/*** 获取单例线程池(默认配置)** @return 单例线程池实例*/public static ThreadPoolExecutor getSingleThreadPoolExecutor() {if (singleThreadPoolExecutor == null) {initializeSingleThreadPoolExecutor();}return singleThreadPoolExecutor;}/*** 初始化单例线程池(懒加载,双重检查锁实现单例)* 1. 单例线程池的创建采用懒加载(Lazy Initialization)方式,即在需要的时候才初始化线程池,避免在类加载时就初始化占用资源。* 2. 使用双重检查锁(Double-Checked Locking)模式,保证线程池的实例化过程是线程安全的,同时避免了不必要的同步开销。* 3. 线程池创建时可以自定义核心线程数、最大线程数、线程空闲时间以及阻塞队列的容量等参数。* 4. 使用自定义线程工厂命名线程,方便日志排查,以及设置线程为守护线程(Daemon Thread)。* 5. 采用 CallerRunsPolicy 拒绝策略,保证在线程池资源耗尽时,任务不会被直接丢弃,而是由调用者线程处理任务。*/private static void initializeSingleThreadPoolExecutor() {if (singleThreadPoolExecutor == null) {synchronized (ThreadPoolManagerUtil.class) {if (singleThreadPoolExecutor == null) {log.info("Initializing single thread pool with custom configuration...");singleThreadPoolExecutor = new ThreadPoolExecutor(ThreadPoolManagerUtil.DEFAULT_CORE_POOL_SIZE,ThreadPoolManagerUtil.DEFAULT_MAXIMUM_POOL_SIZE,ThreadPoolManagerUtil.DEFAULT_KEEP_ALIVE_TIME,TimeUnit.SECONDS,new ArrayBlockingQueue<>(ThreadPoolManagerUtil.DEFAULT_QUEUE_CAPACITY),createCustomThreadFactory("SingleThreadPool"),new ThreadPoolExecutor.CallerRunsPolicy());}}}}/*** 动态调整线程池参数(单例线程池)** @param corePoolSize    新的核心线程数* @param maximumPoolSize 新的最大线程数*/public static void adjustSingleThreadPool(int corePoolSize, int maximumPoolSize) {if (singleThreadPoolExecutor != null) {log.info("Adjusting single thread pool: CorePoolSize={}, MaximumPoolSize={}", corePoolSize, maximumPoolSize);singleThreadPoolExecutor.setCorePoolSize(corePoolSize);singleThreadPoolExecutor.setMaximumPoolSize(maximumPoolSize);}}/*** 优雅关闭单例线程池*/public static void shutdownSingleThreadPool() {if (singleThreadPoolExecutor != null && !singleThreadPoolExecutor.isShutdown()) {log.info("Shutting down single thread pool...");singleThreadPoolExecutor.shutdown();try {if (!singleThreadPoolExecutor.awaitTermination(60, TimeUnit.SECONDS)) {singleThreadPoolExecutor.shutdownNow();}} catch (InterruptedException e) {singleThreadPoolExecutor.shutdownNow();Thread.currentThread().interrupt();}}}/*** 获取多实例线程池(通过名称区分)** @param name            线程池名称* @param corePoolSize    核心线程数* @param maximumPoolSize 最大线程数* @param keepAliveTime   空闲线程存活时间* @param queueCapacity   阻塞队列容量* @return 对应名称的线程池实例*/public static ThreadPoolExecutor getThreadPoolExecutor(String name,int corePoolSize,int maximumPoolSize,long keepAliveTime,int queueCapacity) {return threadPools.computeIfAbsent(name, k -> {log.info("Initializing thread pool: {}", name);return new ThreadPoolExecutor(corePoolSize,maximumPoolSize,keepAliveTime,TimeUnit.SECONDS,new ArrayBlockingQueue<>(queueCapacity),createCustomThreadFactory(name),new ThreadPoolExecutor.CallerRunsPolicy());});}/*** 提供默认配置的多实例线程池** @param name 线程池名称* @return 对应名称的线程池实例*/public static ThreadPoolExecutor getThreadPoolExecutor(String name) {return getThreadPoolExecutor(name, DEFAULT_CORE_POOL_SIZE, DEFAULT_MAXIMUM_POOL_SIZE, DEFAULT_KEEP_ALIVE_TIME, DEFAULT_QUEUE_CAPACITY);}/*** 优雅关闭所有多实例线程池*/public static void shutdownAllThreadPools() {log.info("Shutting down all thread pools...");threadPools.forEach((name, executor) -> {if (!executor.isShutdown()) {log.info("Shutting down thread pool: {}", name);executor.shutdown();try {if (!executor.awaitTermination(60, TimeUnit.SECONDS)) {executor.shutdownNow();}} catch (InterruptedException e) {executor.shutdownNow();Thread.currentThread().interrupt();}}});}/*** 自定义线程工厂,支持线程命名和守护线程** @param threadNamePrefix 线程名前缀* @return 自定义线程工厂*/private static ThreadFactory createCustomThreadFactory(String threadNamePrefix) {return new ThreadFactory() {private final AtomicInteger threadNumber = new AtomicInteger(1);@Overridepublic Thread newThread(Runnable r) {Thread thread = new Thread(r, threadNamePrefix + "-thread-" + threadNumber.getAndIncrement());// 设置为守护线程thread.setDaemon(true);return thread;}};}/*** 获取线程池状态信息** @param executor 线程池实例* @return 线程池状态信息*/public static String getThreadPoolStatus(ThreadPoolExecutor executor) {return String.format("ThreadPool Status: [CorePoolSize: %d, MaximumPoolSize: %d, ActiveCount: %d, QueueSize: %d, CompletedTaskCount: %d]",executor.getCorePoolSize(),executor.getMaximumPoolSize(),executor.getActiveCount(),executor.getQueue().size(),executor.getCompletedTaskCount());}
}

简易使用示例

    public static void main(String[] args) {ThreadPoolExecutor threadPoolExecutor = ThreadPoolManagerUtil.getSingleThreadPoolExecutor();List<String> list = new ArrayList<>();List<CompletableFuture<Void>> futures = list.stream().map(vo -> CompletableFuture.runAsync(() -> {// todo 业务处理// ...// ...
                }, threadPoolExecutor)).toList();// 等待所有任务完成CompletableFuture.allOf(futures.toArray(new CompletableFuture[0])).join();// 根据需要确认是否关闭单例线程池
        ThreadPoolManagerUtil.shutdownSingleThreadPool();}

 

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

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

“代码之舟”——2024秋软工实践纪

这个作业属于哪个课程 https://edu.cnblogs.com/campus/fzu/SE2024这个作业要求在哪里 https://edu.cnblogs.com/campus/fzu/SE2024/homework/13315这个作业的目标 回顾这一学期所完成的软工任务,总结这一学期的收获学号 102202102 王子聪引言: 在上这门课之前还没有真正的体…

Python-DdddOcr的简单使用

前言:我们在做WEB端UI自动化时,会遇到图片验证码校验的登录方式。我在之前的文章也做过介绍:https://www.cnblogs.com/TSmagic/p/16082799.html (Pillow + pytesseract + tesseract-ocr 破解简单的图形验证码)https://www.cnblogs.com/TSmagic/p/16117861.html(Python + 超…

Omnissa ThinApp 2412 - 应用虚拟化软件

Omnissa ThinApp 2412 - 应用虚拟化软件Omnissa ThinApp 2412 - 应用虚拟化软件 Omnissa ThinApp, formerly VMware ThinApp 请访问原文链接:https://sysin.org/blog/omnissa-thinapp/ 查看最新版。原创作品,转载请保留出处。 作者主页:sysin.orgOmnissa ThinApp 通过将应用…

Omnissa App Volumes 4, version 2412 - 实时应用程序交付系统

Omnissa App Volumes 4, version 2412 - 实时应用程序交付系统Omnissa App Volumes 4, version 2412 - 实时应用程序交付系统 Omnissa App Volumes, formerly VMware App Volumes 请访问原文链接:https://sysin.org/blog/omnissa-app-volumes/ 查看最新版。原创作品,转载请保…

CSP-J2/S2 2024 游记

前情提要:CSP-J/S 2023 写这篇文章的时候,心情比较复杂。 哎,结局还算圆满。初赛 之前那个写的不好再写一遍() 两个都在 WFLS,也就是本校考 qaq。 J 在大礼堂考,没啥好说的,太简单了(除了格雷码,好难没学过 /ll) 乐,考试结束前 3min 还在改卷子() 省流:98。 S 在…

部署traefik 1.7服务

部署traefik服务主要是三个yaml文件:traefik-deployment.yaml,traefik-rbac.yaml,ui.yaml也可以使用traefik-ds.yaml,这个方式体现。 [root@k8smaster traefiks]# ll总用量 12-rw-r--r--. 1 root root 1114 12月 26 22:14 traefik-deployment.yaml-rw-r--r--. 1 root root …

2024.12.26 周四

2024.12.26 周四Q1. 1100 There is a ribbon divided into $n$ cells, numbered from $1$ to $n$ from left to right. Initially, an integer $0$ is written in each cell. Monocarp plays a game with a chip. The game consists of several turns. During the first turn, …

UML之集合类型

无论何时当我们要使用一个多值对象时,我们必须要清楚两个问题,一是这些值的顺序重要吗?二是允许重复值的存在吗?在编程语言中还会有其他的明确的信息,在UML中,只需明确这两个问题的答案即可确定对应的集合类型。 1.Set Set是一个不允许存在重复值且未排序的集合。 例如一…

《计算机基础与程序设计》第十四周学习总结

学期(2024-2025-1) 学号(20241412) 《计算机基础与程序设计》第十四周学习总结 作业信息这个作业属于哪个课程 <班级的链接> 2024-2025-1-计算机基础与程序设计这个作业要求在哪里 <作业要求的链接> 2024-2025-1计算机基础与程序设计第十四周作业)教材学习内容…

2024-2025-1 20241417 《计算机基础与程序设计》第十四周学习总结

2024-2025-1 20241417 《计算机基础与程序设计》第十四周学习总结 作业信息这个作业属于哪个课程 <班级的链接>(如2024-2025-1-计算机基础与程序设计)这个作业要求在哪里 <作业要求的链接>2024-2025-1计算机基础与程序设计第十四周作业这个作业的目标 <《C语言…

【Windows】 国内安装Scoop包管理器(镜像加速)

由于国内github访问不通畅,且多数开源软件托管在github,导致scoop体验极差,甚至安装Scoop这一步都无法进行。国内有位作者将scoop主程序托管在gitee,增加分流逻辑处理安装与更新所涉及的资源。 链接: https://gitee.com/scoop-installer/scoop 安装scoop主程序 1.1 初次安…

07 _ Load Average:加了CPU Cgroup限制,为什么我的容器还是很慢?

07 _ Load Average:加了CPU Cgroup限制,为什么我的容器还是很慢?你好,我是程远。今天我想聊一聊平均负载(Load Average)的话题。 在上一讲中,我们提到过CPU Cgroup可以限制进程的CPU资源使用,但是CPU Cgroup对容器的资源限制是存在盲点的。 什么盲点呢?就是无法通过CP…