springboot框架 线程池使用与配置,简单粗暴直接用,再也不用自己创建线程了~

直接上代码:

第一步:配置

java 复制代码
package com.testweb.testweb.threadWeb;

import lombok.extern.slf4j.Slf4j;
import org.springframework.aop.interceptor.AsyncUncaughtExceptionHandler;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.scheduling.annotation.AsyncConfigurer;
import org.springframework.scheduling.annotation.EnableAsync;
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;

import java.util.concurrent.ThreadPoolExecutor;

/**
 * User:Json
 * Date: 2025/12/6
 **/
@Configuration
@EnableAsync  //没有这个注解 线程不会生效
@Slf4j
public class ThreadConfig implements AsyncConfigurer {
    //4 核 CPU / 小型服务器配置  按服务器配置 调整
    private static final int corePoolSize = 4;   // 核心线程数(默认线程数)创建后会在内存里常驻
    private static final int maxPoolSize = 8;    // 最大线程数(包含核心线程),当核心线程和队列满时,最多会创建 4 个非核心线程
    private static final int keepAliveTime = 60;   // 非核心线程空闲回收时间(单位:秒)
    private static final int queueCapacity = 100; // 缓冲队列数

    /**
     * 默认异步线程池 ThreadPoolTaskExecutor 常用
     */
    @Bean("taskExecutor")
    public ThreadPoolTaskExecutor taskExecutor(){
        ThreadPoolTaskExecutor pool = new ThreadPoolTaskExecutor();
        pool.setThreadNamePrefix("DY-Async-Task-"); //线程前缀  便于日志查看
        pool.setCorePoolSize(corePoolSize);
        pool.setMaxPoolSize(maxPoolSize);
        pool.setKeepAliveSeconds(keepAliveTime);
        pool.setQueueCapacity(queueCapacity);
       // pool.setAllowCoreThreadTimeOut(true);//  默认核心线程常驻 如果希望在低配服务器核心线程空闲也释放资源,可加上这行

        // 直接在execute方法的调用线程中运行
        pool.setRejectedExecutionHandler(new ThreadPoolExecutor.CallerRunsPolicy());
        // 初始化
        pool.initialize();
        return pool;
    }

    /**
     * 异步任务异常处理 如果调用的地方 try catch了 这边就不会走了
     */
    @Override
    public AsyncUncaughtExceptionHandler getAsyncUncaughtExceptionHandler() {
        return (ex, method, params) -> {
            log.info("异步任务出现异常: 方法: {}, 参数: {}", method.getName(), params, ex);
        };
    }
}

第二步: 写demo

java 复制代码
package com.testweb.testweb.threadWeb;

import lombok.extern.slf4j.Slf4j;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Service;

import java.util.concurrent.CompletableFuture;

/**
 * User:Json
 * Date: 2025/12/6
 **/
@Service
@Slf4j
public class ThreadService {

    //无返回值
    @Async("taskExecutor")
    public void test() {
        //异常 测试
        // int a=1/0;
        log.info("异步线程");
    }
    //有返回值
    @Async("taskExecutor")
    public CompletableFuture<Integer> asyncCompute(int num) {
        log.info("异步计算开始,线程: {}", Thread.currentThread().getName());
        int result = 10 / num;  // 如果 num=0,会抛异常
        log.info("异步计算结束,结果: {}", result);
        //休息10秒 假装堵塞
        try {
            Thread.sleep(10 * 1000L);
        } catch (InterruptedException e) {
            throw new RuntimeException(e);
        }
        return CompletableFuture.completedFuture(result);
    }
}

第三步:控制器测试:

kotlin 复制代码
package com.testweb.testweb.threadWeb;

import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

import java.util.concurrent.CompletableFuture;

/**
 * User:Json
 * Date: 2025/12/6
 **/
@RestController
@Slf4j
public class ThreadController {

    @Autowired
    ThreadService threadService;

    //无返回值测试
    @GetMapping("testThread")
    public void test() {
        threadService.test();
    }

    //有返回值测试
    @GetMapping("/compute")
    public String testCompute(@RequestParam int num) {
        CompletableFuture<Integer> future = threadService.asyncCompute(num);

        //1. 阻塞情况
//        try {
//            Integer result = future.get(); // 会阻塞,等待返回值
//            log.info("阻塞 计算结果: " + result);
//        } catch (Exception e) {
//            log.info("异步计算异常: {}", e.getMessage(), e);
//        }

        // 2. 不阻塞情况 ,注册回调处理结果
        future.thenAccept(result -> {
            log.info("异步计算完成,不阻塞结果: {}", result);
        }).exceptionally(ex -> {
            log.info("异步计算异常", ex);
            return null;
        });

        return "success";
    }

}

jvm调试测试结果:

在异步方法里写业务逻辑的注意项:

如需补充,欢迎大家留言~

相关推荐
勇哥java实战分享1 天前
程序员的明天:AI 时代下的行业观察与个人思考
后端
掘金码甲哥1 天前
超性感的轻量级openclaw平替,我来给你打call
后端
用户8356290780511 天前
无需 Office:Python 批量转换 PPT 为图片
后端·python
啊哈灵机一动1 天前
使用golang搭建一个nes 模拟器
后端
日月云棠1 天前
各版本JDK对比:JDK 25 特性详解
java
间彧1 天前
SpringBoot + ShardingSphere 读写分离实战指南
后端
砍材农夫1 天前
订单超时
后端
树獭叔叔2 天前
06-大模型如何"学习":从梯度下降到AdamW优化器
后端·aigc·openai
用户8307196840822 天前
Spring Boot 项目中日期处理的最佳实践
java·spring boot
得鹿2 天前
MySQL基础架构与存储引擎、索引、事务、锁、日志
后端