Java注解异步案例如何使用

wen java案例 23

本文目录导读:

Java注解异步案例如何使用

  1. 基础配置
  2. 自定义线程池配置(推荐)
  3. 异步服务示例
  4. 带返回值的异步方法
  5. 控制器调用示例
  6. 完整的实际应用案例
  7. 注意事项
  8. 异常处理

我来详细介绍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注解实现异步的关键点:

  1. 启用注解:使用@EnableAsync
  2. 配置线程池:自定义线程池避免使用默认的SimpleAsyncTaskExecutor
  3. 方法调用:异步方法必须在外部类调用,同一类内调用无效
  4. 返回值:使用FutureCompletableFuture获取异步结果
  5. 异常处理:实现AsyncUncaughtExceptionHandler处理未捕获的异常

这个框架广泛用于邮件发送、报表生成、大数据处理等耗时操作。

抱歉,评论功能暂时关闭!