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

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

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

相关推荐
毕设源码-郭学长5 分钟前
【开题答辩全过程】以 高校图书推荐系统的设计与实现为例,包含答辩的问题和答案
java
主公不搬砖5 分钟前
Nacos 2.5.2 国产信创 kingbase适配
java·docker·nacos·信创·kingbase·国产适配
superman超哥18 分钟前
Rust String与&str的内部实现差异:所有权与借用的典型案例
开发语言·后端·rust·rust string·string与str·内部实现·所有权与借用
谷隐凡二26 分钟前
Kubernetes Route控制器简单介绍
java·容器·kubernetes
Haooog29 分钟前
RAG医疗问答系统
java·大模型·项目·rag
luming-0235 分钟前
报错解决:IDEA终端输出和CMD终端输出Maven版本不一致
java·缓存·bug·intellij-idea
MM_MS39 分钟前
Halcon控制语句
java·大数据·前端·数据库·人工智能·算法·视觉检测
一碗绿豆汤39 分钟前
Java语言概述和开发环境-1
java·开发语言
愈努力俞幸运43 分钟前
rust安装
开发语言·后端·rust
踏浪无痕1 小时前
JobFlow 负载感知调度:把任务分给最闲的机器
后端·架构·开源