本文目录导读:

我来详细介绍Java中如何使用注解实现异步处理,主要基于Spring框架的@Async注解。
基础配置
启用异步支持
import org.springframework.context.annotation.Configuration;
import org.springframework.scheduling.annotation.EnableAsync;
@Configuration
@EnableAsync // 启用异步支持
public class AsyncConfig {
// 可以自定义线程池
}
自定义线程池配置(推荐)
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.scheduling.annotation.EnableAsync;
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;
import java.util.concurrent.Executor;
import java.util.concurrent.ThreadPoolExecutor;
@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-task-");
// 拒绝策略
executor.setRejectedExecutionHandler(new ThreadPoolExecutor.CallerRunsPolicy());
// 等待所有任务完成再关闭
executor.setWaitForTasksToCompleteOnShutdown(true);
// 等待时间
executor.setAwaitTerminationSeconds(60);
executor.initialize();
return executor;
}
}
异步服务示例
简单异步方法
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Service;
@Service
public class AsyncService {
@Async // 标记为异步方法
public void sendEmail(String email) {
System.out.println("发送邮件开始: " + Thread.currentThread().getName());
try {
// 模拟耗时操作
Thread.sleep(3000);
System.out.println("发送邮件给: " + email);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("发送邮件结束");
}
@Async("taskExecutor") // 指定线程池
public void processOrder(Long orderId) {
System.out.println("处理订单: " + orderId + " - " + Thread.currentThread().getName());
// 处理订单逻辑
}
}
带返回值的异步方法
import org.springframework.scheduling.annotation.Async;
import org.springframework.scheduling.annotation.AsyncResult;
import org.springframework.stereotype.Service;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.Future;
@Service
public class AsyncResultService {
// 返回Future对象
@Async
public Future<String> processData(String data) {
System.out.println("处理数据开始: " + Thread.currentThread().getName());
try {
Thread.sleep(2000);
String result = "处理结果: " + data.toUpperCase();
return new AsyncResult<>(result);
} catch (InterruptedException e) {
return new AsyncResult<>("处理失败");
}
}
// 返回CompletableFuture (推荐)
@Async
public CompletableFuture<User> findUser(Long userId) {
System.out.println("查询用户: " + Thread.currentThread().getName());
// 模拟查询
User user = new User(userId, "User" + userId);
return CompletableFuture.completedFuture(user);
}
// 多个异步调用的组合
@Async
public CompletableFuture<String> combineResults() {
// 模拟组合多个结果
return CompletableFuture.supplyAsync(() -> {
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
return "组合结果";
});
}
}
// 用户实体类
class User {
private Long id;
private String name;
public User(Long id, String name) {
this.id = id;
this.name = name;
}
// getter/setter
}
控制器调用示例
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.Future;
@RestController
@RequestMapping("/async")
public class AsyncController {
@Autowired
private AsyncService asyncService;
@Autowired
private AsyncResultService asyncResultService;
// 无返回值的异步调用
@GetMapping("/send-email")
public String sendEmail(@RequestParam String email) {
System.out.println("主线程: " + Thread.currentThread().getName());
// 异步调用,立即返回
asyncService.sendEmail(email);
return "邮件已开始发送";
}
// 带返回值的异步调用
@GetMapping("/process/{data}")
public String processData(@PathVariable String data) throws ExecutionException, InterruptedException {
Future<String> future = asyncResultService.processData(data);
// 检查是否完成
if (future.isDone()) {
return future.get(); // 获取结果
} else {
return "正在处理中...";
}
}
// 等待异步结果
@GetMapping("/wait-result/{data}")
public String waitForResult(@PathVariable String data) throws ExecutionException, InterruptedException {
Future<String> future = asyncResultService.processData(data);
// 等待结果,最多等待5秒
String result = future.get(); // 阻塞直到结果返回
return result;
}
}
完整的实际应用案例
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Service;
import java.util.concurrent.CompletableFuture;
@Service
public class OrderService {
/**
* 异步处理订单
*/
@Async("taskExecutor")
public CompletableFuture<OrderResult> processOrderAsync(Order order) {
OrderResult result = new OrderResult();
try {
// 1. 验证订单
validateOrder(order);
// 2. 处理支付
processPayment(order);
// 3. 更新库存
updateInventory(order);
// 4. 发送通知
sendNotification(order);
result.setSuccess(true);
result.setOrderId(order.getId());
result.setMessage("订单处理成功");
} catch (Exception e) {
result.setSuccess(false);
result.setMessage("订单处理失败: " + e.getMessage());
}
return CompletableFuture.completedFuture(result);
}
private void validateOrder(Order order) {
// 验证逻辑
System.out.println("验证订单: " + order.getId());
}
private void processPayment(Order order) {
// 支付逻辑
System.out.println("处理支付: " + order.getId());
}
private void updateInventory(Order order) {
// 库存逻辑
System.out.println("更新库存: " + order.getId());
}
private void sendNotification(Order order) {
// 通知逻辑
System.out.println("发送通知: " + order.getId());
}
}
// 订单结果类
class OrderResult {
private boolean success;
private Long orderId;
private String message;
// getter/setter
}
注意事项
// 重要:异步方法的限制
@Service
public class AsyncDemoService {
// 错误示例:同一类中调用异步方法不会生效
public void methodA() {
this.methodB(); // 不会异步执行!
}
@Async
public void methodB() {
// 异步逻辑
}
// 正确示例:注入自身
@Autowired
private AsyncDemoService self;
public void methodC() {
self.methodB(); // 会异步执行
}
}
异常处理
import org.springframework.aop.interceptor.AsyncUncaughtExceptionHandler;
import org.springframework.context.annotation.Configuration;
import org.springframework.scheduling.annotation.AsyncConfigurer;
import java.lang.reflect.Method;
import java.util.concurrent.Executor;
@Configuration
public class AsyncExceptionConfig implements AsyncConfigurer {
@Override
public Executor getAsyncExecutor() {
// 返回自定义线程池
return null;
}
@Override
public AsyncUncaughtExceptionHandler getAsyncUncaughtExceptionHandler() {
return new AsyncUncaughtExceptionHandler() {
@Override
public void handleUncaughtException(Throwable ex, Method method, Object... params) {
System.out.println("异步方法异常: " + method.getName());
System.out.println("异常信息: " + ex.getMessage());
// 记录日志或发送通知
}
};
}
}
使用@Async注解实现异步的关键点:
- 启用注解:使用
@EnableAsync - 配置线程池:自定义线程池避免使用默认的SimpleAsyncTaskExecutor
- 方法调用:异步方法必须在外部类调用,同一类内调用无效
- 返回值:使用
Future或CompletableFuture获取异步结果 - 异常处理:实现
AsyncUncaughtExceptionHandler处理未捕获的异常
这个框架广泛用于邮件发送、报表生成、大数据处理等耗时操作。
版权声明:足球直播
足球直播
足球直播
足球直播
足球直播
中超直播
中超直播
中超直播
中超直播
中超直播
英超直播
英超直播
英超直播
英超直播
英超直播
德甲直播
德甲直播
德甲直播
德甲直播
德甲直播
西甲直播
西甲直播
西甲直播
西甲直播
西甲直播
意甲直播
意甲直播
意甲直播
意甲直播
意甲直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
篮球直播
篮球直播
篮球直播
篮球直播
篮球直播
足球直播
足球直播
足球直播
足球直播
足球直播
中超直播
中超直播
中超直播
中超直播
中超直播
英超直播
英超直播
英超直播
英超直播
英超直播
德甲直播
德甲直播
德甲直播
德甲直播
德甲直播
西甲直播
西甲直播
西甲直播
西甲直播
西甲直播
意甲直播
意甲直播
意甲直播
意甲直播
意甲直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
篮球直播
篮球直播
篮球直播
篮球直播
篮球直播
足球直播
足球直播
足球直播
足球直播
足球直播
中超直播
中超直播
中超直播
中超直播
中超直播
英超直播
英超直播
英超直播
英超直播
英超直播
德甲直播
德甲直播
德甲直播
德甲直播
德甲直播
西甲直播
西甲直播
西甲直播
西甲直播
西甲直播
意甲直播
意甲直播
意甲直播
意甲直播
意甲直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
篮球直播
篮球直播
篮球直播
篮球直播
篮球直播