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

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

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

相关推荐
wuminyu3 小时前
JVM规范学习总结:解释器与JIT编译器如何处理JVM字节码
java·linux·c语言·jvm·c++
txxzjmzlh3 小时前
SpringBoot 配置⽂件
java·spring boot·spring
ZhengEnCi4 小时前
模型训练完整流程:从数据准备到模型上线的 10 个关键步骤(全文可跑)
后端·算法
王中阳Go4 小时前
后端转 Agent 岗面试怎么答:8 个高频问题与应答口径
人工智能·后端·python·大语言模型
Wang's Blog4 小时前
Java 项目实战: 交友项目 - 搜索附近的功能概述和分析
java·开发语言·交友
程序猿DD4 小时前
OctaFuse Gateway 2.18.0:MCP 接入支持 OAuth,供应商粘性绑定可视化管理
后端
骑着蜗牛撵大象3274 小时前
大模型 Agent 的沙箱护栏:gVisor 隔离、出口白名单与审计闭环
java·开发语言·jvm·安全·agent沙箱·gvisor·microvm
独泪了无痕4 小时前
Hutool之LocalDateTimeUtil:让时间间隔操作如虎添翼
java
三无少女指南6 小时前
从这里开始:Java 后端与 AI 工程的三条阅读路线
java·学习路线·ai工程
ZhengEnCi6 小时前
Agent 规则管理:让 Memory 做索引、让 Skill 存规则——上下文上限实测与分工方案
后端