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调试测试结果:

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

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

相关推荐
葫芦和十三3 小时前
图解 MongoDB 22|读写关注:持久性与一致性的档位选择
后端·mongodb·agent
葫芦和十三10 小时前
图解 MongoDB 21|选举与 failover:Primary 是怎么选出来的
后端·mongodb·agent
GetcharZp10 小时前
26k Star 开源内网穿透神器 NetBird,一分钟实现全球设备互联!
后端
考虑考虑11 小时前
Mybatis实现批量插入
java·后端·mybatis
咖啡八杯12 小时前
GoF设计模式——中介者模式
java·后端·spring·设计模式
lizhongxuan14 小时前
多Agent之间的区别
后端
青石路15 小时前
记一次多JDK版本问题的排查,一坑套一坑,差点没爬上来
java
杨充16 小时前
1.面向对象设计思想
后端
IT_陈寒16 小时前
Java的Date类又坑了我一次,改用时间戳真香
前端·人工智能·后端
systemPro17 小时前
2.6亿条设备数据,历史查询从超时到50ms,我做了什么
后端