Spring Boot 多线程池统一配置与使用教程

🌟 Spring Boot 多线程池统一配置与使用教程

本人通过以下类实现了多线程池的统一管理、异常安全包装、日志输出与监控:

  • TaskThreadPoolConfig.java:多线程池配置类
  • ExecutorBuilder.java:通用线程池构建器
  • ExceptionSafeRunnable.java:线程任务异常封装器
  • ThreadPoolMonitorUtils.java:线程池状态监控工具
  • application.yml:集中配置参数

🧱 1. 配置文件 application.yml

thread-pool:
  common:
    core: 8 # 核心线程数
    max: 16 # 最大线程数
    queue: 200 # 队列容量
    keepalive: 60 # 线程空闲时间 (秒)
    prefix: "common-task-" # 线程前缀名

  file:
    core: 6
    max: 12
    queue: 200
    keepalive: 120
    prefix: "file-task-"

  websocket:
    core: 2
    max: 4
    queue: 50
    keepalive: 30
    prefix: "ws-task-"

  schedule:
    core: 2
    max: 4
    queue: 100
    keepalive: 60
    prefix: "schedule-task-"

🧩 2. 线程池构建器 ExecutorBuilder.java

⚠️ 这里使用了new ThreadPoolExecutor.CallerRunsPolicy()ThreadPoolExecutor是java的,并不是spring的,请注意。此方法为拒绝策略,拒绝策略自行搜索,本人使用的是 CallerRunsPolicy(),由调用线程处理该任务

import java.util.concurrent.ThreadPoolExecutor;

public class ExecutorBuilder {
    
    public static ThreadPoolTaskExecutor build(
            int corePoolSize,
            int maxPoolSize,
            int queueCapacity,
            int keepAliveSeconds,
            String threadNamePrefix
    ) {
        ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
        executor.setCorePoolSize(corePoolSize);
        executor.setMaxPoolSize(maxPoolSize);
        executor.setQueueCapacity(queueCapacity);
        executor.setKeepAliveSeconds(keepAliveSeconds);
        executor.setThreadNamePrefix(threadNamePrefix);
        executor.setRejectedExecutionHandler(new ThreadPoolExecutor.CallerRunsPolicy());
        executor.setWaitForTasksToCompleteOnShutdown(true);
        executor.setAwaitTerminationSeconds(60);
        executor.initialize();
        return executor;
    }
}

⚙️ 3. 多线程池配置类 TaskThreadPoolConfig.java

⚠️ 这里根据项目自行选择,个人建议不同操作可以分开管理,本人这里分了 4大类,主要使用了common和io,可以有限避免因为io操作慢导致其他操作不可用。

@Configuration
public class TaskThreadPoolConfig {

    @Bean("commonTaskExecutor")
    public ThreadPoolTaskExecutor commonTaskExecutor(
            @Value("${thread-pool.common.core}") int core,
            @Value("${thread-pool.common.max}") int max,
            @Value("${thread-pool.common.queue}") int queue,
            @Value("${thread-pool.common.keepalive}") int keepalive,
            @Value("${thread-pool.common.prefix}") String prefix) {
        return ExecutorBuilder.build(core, max, queue, keepalive, prefix);
    }

    @Bean("fileTaskExecutor")
    public ThreadPoolTaskExecutor fileTaskExecutor(
            @Value("${thread-pool.file.core}") int core,
            @Value("${thread-pool.file.max}") int max,
            @Value("${thread-pool.file.queue}") int queue,
            @Value("${thread-pool.file.keepalive}") int keepalive,
            @Value("${thread-pool.file.prefix}") String prefix) {
        return ExecutorBuilder.build(core, max, queue, keepalive, prefix);
    }

    @Bean("websocketPushExecutor")
    public ThreadPoolTaskExecutor websocketPushExecutor(
            @Value("${thread-pool.websocket.core}") int core,
            @Value("${thread-pool.websocket.max}") int max,
            @Value("${thread-pool.websocket.queue}") int queue,
            @Value("${thread-pool.websocket.keepalive}") int keepalive,
            @Value("${thread-pool.websocket.prefix}") String prefix) {
        return ExecutorBuilder.build(core, max, queue, keepalive, prefix);
    }

    @Bean("scheduleTaskExecutor")
    public ThreadPoolTaskExecutor scheduleTaskExecutor(
            @Value("${thread-pool.schedule.core}") int core,
            @Value("${thread-pool.schedule.max}") int max,
            @Value("${thread-pool.schedule.queue}") int queue,
            @Value("${thread-pool.schedule.keepalive}") int keepalive,
            @Value("${thread-pool.schedule.prefix}") String prefix) {
        return ExecutorBuilder.build(core, max, queue, keepalive, prefix);
    }
}

🛡 4. 异常安全封装器 ExceptionSafeRunnable.java

⚠️ 此方法是为了抛出异常,可不用

@Log4j2
public class ExceptionSafeRunnable implements Runnable {

    private final Runnable task;
    private final String taskName; // 可选,便于日志标识

    public ExceptionSafeRunnable(Runnable task, String taskName) {
        this.task = task;
        this.taskName = taskName;
    }

    @Override
    public void run() {
        try {
            task.run();
        } catch (Throwable ex) {
            // 统一异常处理逻辑
            log.error("[线程异常] 任务: {},异常信息: {}", taskName, ex.getMessage(), ex);
        }
    }

    public static Runnable wrap(Runnable task, String taskName) {
        return new ExceptionSafeRunnable(task, taskName);
    }
}

📊 5. 线程池监控工具类 ThreadPoolMonitorUtils.java

@Slf4j
public class ThreadPoolMonitorUtils {

    /**
     * 打印线程池运行状态
     *
     * @param executor 线程池
     * @param name     线程池名称(用于日志标识)
     */
    public static void printState(ThreadPoolTaskExecutor executor, String name) {
        ThreadPoolExecutor pool = executor.getThreadPoolExecutor();

        log.info("线程池 [{}] 状态:", name);
        log.info(" - 核心线程数:      {}", pool.getCorePoolSize());
        log.info(" - 最大线程数:      {}", pool.getMaximumPoolSize());
        log.info(" - 当前活跃线程数:  {}", pool.getActiveCount());
        log.info(" - 当前任务数:      {}", pool.getTaskCount());
        log.info(" - 已完成任务数:    {}", pool.getCompletedTaskCount());
        log.info(" - 当前队列大小:    {}", pool.getQueue().size());
        log.info(" - 队列剩余容量:    {}", pool.getQueue().remainingCapacity());
    }
}

🚀 6. 启用异步支持(如使用 @Async)

在启动类或配置类添加:

@EnableAsync
@SpringBootApplication
public class Application { ... }

🧪 7. 使用示例

注入线程池:

@Resource(name = "commonTaskExecutor")
private ThreadPoolTaskExecutor commonExecutor;

提交任务(带异常封装):

commonExecutor.execute(ExceptionSafeRunnable.wrap(() -> {
    // 异步任务内容
}, "业务处理任务"));

提交任务(无异常封装):

commonExecutor.execute( () -> {
	// 异步任务内容
})

📡 8. 可选:定时打印线程池状态

⚠️ 这里可以自行扩展,可以通过接口、定时任务等使用
⚠️ 使用@Scheduled请确保项目添加了 @EnableScheduling 注解。

@Scheduled(fixedRate = 30000)
public void monitor() {
    ThreadPoolMonitorUtils.printState(commonExecutor, "通用线程池");
}

✅ 总结推荐

推荐实践建议说明
拆分多线程池根据业务类型独立配置,防止互相干扰
统一构建器避免重复代码
异常封装器所有任务包装为 ExceptionSafeRunnable,防止吞异常
监控工具开发/线上查看线程使用情况
@EnableAsync若使用 @Async,必须开启
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值