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

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

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

相关推荐
YOU OU7 分钟前
Spring IoC&DI
java·数据库·spring
один but you32 分钟前
从可变参数到 emplace:现代 C++ 性能优化的核心组合
java·开发语言
IT_陈寒32 分钟前
Redis缓存击穿把我整不会了,原来还有这手操作
前端·人工智能·后端
是码龙不是码农1 小时前
ThreadPoolExecutor 7 个核心参数详解
java·线程池·threadpool
kyriewen1 小时前
面试官让我查各部门工资最高的员工,我用AI三秒写出窗口函数,他愣了
后端·mysql·面试
这是程序猿1 小时前
Spring Boot自动配置详解
java·大数据·前端
文心快码BaiduComate1 小时前
干货|Comate Harness Engineering工程实践指南
前端·后端·程序员
光辉GuangHui1 小时前
Agent Skill 也需要测试:如何搭建 Skill 评估框架
前端·后端·llm
MY_TEUCK1 小时前
【Java 后端 | Nacos 注册中心】微服务治理原理、选型与注册发现实战
java·开发语言·微服务
我是谁的程序员1 小时前
Mac 上生成 AppStoreInfo.plist 文件,App Store 上架
后端·ios