自定义线程名称,参数,如果不设置则默认使用配置文件参数,以下所有参数
1、int corePoolSize 核心线程数
2、int maximumPoolSize 最大线程数
3、long keepAliveTime 空闲线程的存活时间
4、TimeUnit unit keepAliveTime的时间单位
5、BlockingQueue<Runnable> workQueue 任务队列
6、ThreadFactory threadFactory 线程工厂,用来创建新线程
7、RejectedExecutionHandler handler 处理被拒绝的任务
开始
引入谷歌guava jar
<!-- guava -->
<dependency>
<groupId>com.google.guava</groupId>
<artifactId>guava</artifactId>
<version>31.1-jre</version>
</dependency>
yml配置文件(默认使用这些参数)
threadPool:
# 核心线程池大小
corePoolSize: 5
# 最大线程数
maxPoolSize: 20
# 缓冲队列大小
queueCapacity: 200
# 允许线程空闲时间(单位:默认为秒)
keepAliveTime: 60
# 线程池名前缀
threadNamePrefix: Thread-Pool
配置文件
import lombok.Data;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Configuration;
/**
* @Description 线程池配置
* @Author WangKun
* @Date 2024/3/5 17:40
* @Version
*/
@Data
@Configuration
public class ThreadPoolConfig {
/**
* 获取系统的CPU个数
*/
public static final int CPU_NUMS = Runtime.getRuntime().availableProcessors();
/**
* 核心线程池大小
*/
public static int corePoolSize;
/**
* 最大线程数
*/
public static int maxPoolSize;
/**
* 缓冲队列大小
*/
public static int queueCapacity;
/**
* 允许线程空闲时间(单位:默认为秒)
*/
public static int keepAliveTime;
/**
* 线程池名前缀
*/
public static String threadNamePrefix;
@Value("${threadPool.corePoolSize}")
public void setCorePoolSize(int corePoolSize) {
ThreadPoolConfig.corePoolSize = corePoolSize;
}
@Value("${threadPool.maxPoolSize}")
public void setMaxPoolSize(int maxPoolSize) {
ThreadPoolConfig.maxPoolSize = maxPoolSize;
}
@Value("${threadPool.queueCapacity}")
public void setQueueCapacity(int queueCapacity) {
ThreadPoolConfig.queueCapacity = queueCapacity;
}
@Value("${threadPool.keepAliveTime}")
public void setKeepAliveTime(int keepAliveTime) {
ThreadPoolConfig.keepAliveTime = keepAliveTime;
}
@Value("${threadPool.threadNamePrefix}")
public void setThreadNamePrefix(String threadNamePrefix) {
ThreadPoolConfig.threadNamePrefix = threadNamePrefix;
}
}
线程池封装
import java.util.concurrent.ArrayBlockingQueue;
import java.util.concurrent.BlockingQueue;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.RejectedExecutionHandler;
import java.util.concurrent.ThreadFactory;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;
import com.google.common.util.concurrent.ThreadFactoryBuilder;
import org.apache.commons.lang3.StringUtils;
/**
* @Description 线程池工具
* 异步使用,在其方法上打上注解 @Async, 否则则同步
* 1: 无返回值时使用:execute 执行 会抛出异常
* 2:有返回值时使用:submit 执行 不会抛出异常
* @Author WangKun
* @Date 2024/8/15 17:02
* @Version
*/
public class ThreadPoolUtils {
/**
* @param
* @Description 创建线程池
* @Throws
* @Return com.threadpool.ThreadPoolUtils.Builder
* @Date 2024-08-16 18:06:33
* @Author WangKun
**/
public static ThreadPoolUtils.Builder create() {
return new ThreadPoolUtils.Builder();
}
/**
* @Description 构建线程池参数
* @Throws
* @Return
* @Date 2024-08-16 18:06:50
* @Author WangKun
**/
public static class Builder {
private String threadNamePrefix;
private Integer corePoolSize;
private Integer maxPoolSize;
private Long keepAliveTime;
private TimeUnit timeUnit;
private BlockingQueue<Runnable> queueCapacity;
private RejectedExecutionHandler handler;
/**
* @param
* @Description 构建参数
* @Throws
* @Return java.util.concurrent.ExecutorService
* @Date 2024-08-16 18:07:13
* @Author WangKun
**/
public ExecutorService build() {
String defaultName = ThreadPoolConfig.threadNamePrefix;
int defaultCoreSize = ThreadPoolConfig.CPU_NUMS * ThreadPoolConfig.corePoolSize;
int defaultMaxSize = ThreadPoolConfig.CPU_NUMS * ThreadPoolConfig.maxPoolSize;
long defaultAliveTime = ThreadPoolConfig.keepAliveTime;
int defaultQueueCapacity = ThreadPoolConfig.queueCapacity;
TimeUnit defaultTimeUnit = TimeUnit.SECONDS;
final String poolName = StringUtils.isNotEmpty(threadNamePrefix) && StringUtils.isNoneBlank(threadNamePrefix) ? threadNamePrefix : defaultName;
final int cPoolSize = corePoolSize != null ? corePoolSize : defaultCoreSize;
final int mPoolSize = maxPoolSize != null ? maxPoolSize : defaultMaxSize;
final long kpAliveTime = keepAliveTime != null ? keepAliveTime : defaultAliveTime;
final BlockingQueue<Runnable> blockingQueue = queueCapacity != null ? queueCapacity : new ArrayBlockingQueue<Runnable>(defaultQueueCapacity);
final TimeUnit unit = timeUnit != null ? timeUnit : defaultTimeUnit;
final ThreadFactory threadsFactory = new ThreadFactoryBuilder().setNameFormat(poolName + "-%d").build();
final RejectedExecutionHandler executionHandler = handler != null ? handler : new ThreadPoolExecutor.CallerRunsPolicy();
return new ThreadPoolExecutor(cPoolSize, mPoolSize, kpAliveTime, unit, blockingQueue, threadsFactory, executionHandler);
}
/**
* @param threadNamePrefix
* @Description 设置线程池名称
* @Throws
* @Return com.threadpool.ThreadPoolUtils.Builder
* @Date 2024-08-16 18:10:13
* @Author WangKun
**/
public Builder setPrefixName(String threadNamePrefix) {
this.threadNamePrefix = threadNamePrefix;
return this;
}
/**
* @param corePoolSize
* @Description 设置线程池核心数大小(默认为:CPU * 配置文件配置的大小)
* @Throws
* @Return com.threadpool.ThreadPoolUtils.Builder
* @Date 2024-08-16 18:10:30
* @Author WangKun
**/
public Builder setCorePoolSize(Integer corePoolSize) {
this.corePoolSize = corePoolSize;
return this;
}
/**
* @param maxPoolSize
* @Description 设置最大线程数大小(默认为:CPU * 配置文件配置的大小)
* @Throws
* @Return com.threadpool.ThreadPoolUtils.Builder
* @Date 2024-08-16 18:11:26
* @Author WangKun
**/
public Builder setMaxPoolSize(Integer maxPoolSize) {
this.maxPoolSize = maxPoolSize;
return this;
}
/**
* @param keepAliveTime
* @Description 允许线程空闲时间(单位:默认为秒)
* @Throws
* @Return com.threadpool.ThreadPoolUtils.Builder
* @Date 2024-08-16 18:12:33
* @Author WangKun
**/
public Builder setKeepAliveTime(Long keepAliveTime) {
this.keepAliveTime = keepAliveTime;
return this;
}
/**
* @param timeUnit
* @Description 设置线程池的时间单位(默认:TimeUnit.SECONDS)
* @Throws
* @Return com.threadpool.ThreadPoolUtils.Builder
* @Date 2024-08-16 18:13:29
* @Author WangKun
**/
public Builder setTimeUnit(TimeUnit timeUnit) {
this.timeUnit = timeUnit;
return this;
}
/**
* @param queueCapacity
* @Description 设置线程池缓冲队列大小
* @Throws
* @Return com.threadpool.ThreadPoolUtils.Builder
* @Date 2024-08-16 18:13:24
* @Author WangKun
**/
public Builder setQueueCapacity(BlockingQueue<Runnable> queueCapacity) {
this.queueCapacity = queueCapacity;
return this;
}
/**
* @param handler
* @Description 设置线程池拒绝策略 (默认:CallerRunsPolicy)
* rejection-policy:拒绝策略, 当线程数已经达到maxSize时候,如何处理新任务
* CallerRunsPolicy():交由调用方线程运行,比如main线程,如果添加到线程池失败,那么主线程会自己去执行该任务,不会等待线程池中的线程去执行
* AbortPolicy():该策略时线程池的默认策略,如果线程池队列满了丢掉这个任务并且抛出RejectedExecutionException
* DiscardPolicy():如果线程池队列满了,会直接丢掉这个任务并且不会有任何异常
* DiscardOldestPolicy():丢弃队列中最老的任务,队列满了,会将最早进入队列的任务删掉腾出空间,再尝试加入队列
* @Throws
* @Return com.threadpool.ThreadPoolUtils.Builder
* @Date 2024-08-16 18:14:55
* @Author WangKun
**/
public Builder setHandler(RejectedExecutionHandler handler) {
this.handler = handler;
return this;
}
}
}
借鉴博客地址:
https://download.csdn.net/download/u013390913/10762563
使用方法示例:
// 只设置自定义线程名
ExecutorService executorService = ThreadPoolUtils.create().setPrefixName("线程池自定义名称方便溯源").build();
// 执行
executorService.execute(() -> {
log.info("线程池自定义名称方便溯源");
});
// 设置多个参数(多个参数就调用set方法)
ExecutorService executorService = ThreadPoolUtils.create().setPrefixName("线程池自定义名称方便溯源").setCorePoolSize(6).build();
// 执行
executorService.execute(() -> {
log.info("线程池自定义名称方便溯源");
});