import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.scheduling.annotation.EnableAsync;
@SpringBootApplication
@EnableAsync // 开启异步任务支持
public class Application {
public static void main(String[] args) {
SpringApplication.run(Application.class, args);
}
}
在需要异步执行的方法上使用 @Async
注解:
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Service;
@Service
public class AsyncService {
@Async // 标记为异步方法
public void doAsyncTask() {
System.out.println("异步任务开始执行,线程名:" + Thread.currentThread().getName());
try {
Thread.sleep(3000); // 模拟耗时操作
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
}
System.out.println("异步任务执行完成");
}
@Async
public CompletableFuture<String> doAsyncTaskWithResult() {
System.out.println("带返回值的异步任务,线程名:" + Thread.currentThread().getName());
try {
Thread.sleep(2000);
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
}
return CompletableFuture.completedFuture("任务完成");
}
}
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
@RestController
public class TestController {
@Autowired
private AsyncService asyncService;
@GetMapping("/test-async")
public String testAsync() {
System.out.println("主线程开始:" + Thread.currentThread().getName());
asyncService.doAsyncTask(); // 异步执行,不会阻塞
System.out.println("主线程结束");
return "请求已接收";
}
}
虽然 @EnableAsync
可以工作,但默认使用的是 SimpleAsyncTaskExecutor
,不适合生产环境。推荐自定义线程池。
import org.springframework.context.annotation.Configuration;
import org.springframework.scheduling.annotation.EnableAsync;
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;
import java.util.concurrent.Executor;
@Configuration
@EnableAsync
public class AsyncConfig {
@Bean("taskExecutor")
public Executor taskExecutor() {
ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
executor.setCorePoolSize(5); // 核心线程数
executor.setMaxPoolSize(10); // 最大线程数
executor.setQueueCapacity(100); // 队列大小
executor.setThreadNamePrefix("async-"); // 线程前缀名
executor.setRejectedExecutionHandler(new ThreadPoolExecutor.CallerRunsPolicy()); // 拒绝策略
executor.initialize(); // 初始化
return executor;
}
}
线程池@Bean名称注意事项:
默认线程池的创建逻辑
当 Spring 启动并处理
@EnableAsync
注解时,它会按照以下顺序查找或创建一个Executor
(即线程池):
- 查找名为
taskExecutor
的Executor
Bean
Spring 会首先检查容器中是否存在一个名为taskExecutor
的Executor
类型的 Bean。如果存在,就使用它。- 如果没有找到
taskExecutor
,则使用默认的SimpleAsyncTaskExecutor
如果你没有定义taskExecutor
Bean,Spring 会自动创建一个默认的SimpleAsyncTaskExecutor
实例来执行异步任务。
@Service
public class AsyncService {
@Async("taskExecutor") // 指定使用名为 taskExecutor 的线程池
public void doAsyncWithCustomPool() {
System.out.println("使用自定义线程池执行,线程名:" + Thread.currentThread().getName());
}
}
import org.springframework.aop.interceptor.AsyncUncaughtExceptionHandler;
import org.springframework.context.annotation.Configuration;
import java.lang.reflect.Method;
@Configuration
public class CustomAsyncExceptionHandler implements AsyncUncaughtExceptionHandler {
@Override
public void handleUncaughtException(Throwable throwable, Method method, Object... objects) {
System.err.println("异步方法抛出异常: " + method.getName());
throwable.printStackTrace();
}
}
然后在 AsyncConfig
中注册:
@Override
public AsyncUncaughtExceptionHandler getAsyncUncaughtExceptionHandler() {
return new CustomAsyncExceptionHandler();
}
void
:最简单,不关心结果。Future<T>
/ CompletableFuture<T>
:可用于获取执行结果或处理回调。@Async
public CompletableFuture<String> asyncProcess() {
// 模拟处理
return CompletableFuture.completedFuture("处理完成");
}
// 调用处
CompletableFuture<String> future = asyncService.asyncProcess();
future.thenAccept(result -> System.out.println("结果:" + result));
方案 | 优点 | 缺点 | 适用场景 |
---|---|---|---|
注解方案(@EnableAsync) | 简单快捷,开箱即用 | 使用默认线程池,不适合高并发 | 快速原型、低并发场景 |
代码配置方案(自定义线程池) | 可控性强,性能好,适合生产 | 需要额外配置 | 生产环境、高并发任务 |
https://blog.xqlee.com/article/2509151249071046.html