项目中用过的@Async注解使用

本文介绍了如何在Spring中配置线程池,包括核心线程数、最大线程数、存活时间和队列容量等参数,并展示了如何使用`@Async`注解实现异步任务,通过`ThreadPoolTaskExecutor`处理并发请求,提高系统性能。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

spring托管线程池配置

threadPool:
  maxPoolSize: 30
  keepAliveTime: 60
  queueCapacity: 1000
  corePoolSize: 10
@Configuration
@EnableAsync
public class ThreadPoolTaskConfig {

    @Value("${threadPool.corePoolSize}")
    private int corePoolSize;
    @Value("${threadPool.maxPoolSize}")
    private int maxPoolSize;
    @Value("${threadPool.keepAliveTime}")
    private int keepAliveTime;
    @Value("${threadPool.queueCapacity}")
    private int queueCapacity;

    private ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();

    @Bean("taskExecutor")
    public ThreadPoolTaskExecutor taskExecutor(){
        executor.setCorePoolSize(corePoolSize);
        executor.setMaxPoolSize(maxPoolSize);
        executor.setQueueCapacity(queueCapacity);
        executor.setKeepAliveSeconds(keepAliveTime);
        // 线程池对拒绝任务的处理策略
        // CallerRunsPolicy:由调用线程(提交任务的线程)处理该任务
        executor.setRejectedExecutionHandler(new ThreadPoolExecutor.CallerRunsPolicy());
        // 初始化
        executor.initialize();
        return executor;
    }
}

使用

// 省略service接口
@Service
public class ChannelPageServiceImpl implements ChannelPageService {
    @Resource
    private ChannelPageAsyncService channelPageAsyncService;
    @Override
    public ChannelPageDTO getChannelPage(Long userId, RequestTerminal terminal) throws Exception {
        ChannelPageDTO channelPage = new ChannelPageDTO();
        Future<WelfareDTO> welFareFuture1 = channelPageAsyncService.getWelFareVOByType();
        Future<WelfareDTO> welFareFuture2 = channelPageAsyncService.getWelFareVOByType();
        Future<ArticleDTO> articleFuture = channelPageAsyncService.getArticleVO();
        Future<CardDTO> cardDTOFuture = channelPageAsyncService.getCardDTO();
        
        // 最后统一get(get操作是阻塞操作)
        WelfareDTO welfareDTO1 = welFareFuture1.get();
        WelfareDTO welfareDTO2 = welFareFuture2.get();
        ArticleDTO articleDTO = articleFuture.get();
        cardDTO = cardDTOFuture.get();

        channelPage.setWelfareDTO1(welfareDTO1);
        channelPage.setWelfareDTO2(welfareDTO2);
        channelPage.setArticleDTO(articleDTO);
        channelPage.setCardDTO(cardDTO);
        return channelPage;
    }
}

// 省略service接口
// 此注解可以加载类上也可以加在方法上
@Async(value = "taskExecutor")
@Slf4j
@Service
public class ChannelPageAsyncServiceImpl implements ChannelPageAsyncService {
    @Override
    public Future<WelfareDTO> getWelFareVOByType() {
        WelfareDTO welfareDTO = new WelfareDTO();
        // doSth
        return new AsyncResult<>(welfareDTO);
    }
    
    @Override
    public Future<ArticleDTO> getArticleVO() {
        ArticleDTO articleDTO = new ArticleDTO();
        // // doSth
        return new AsyncResult<>(articleDTO);
    }

    // 省略其他方法
}
<think>嗯,用户问的是在Java中,如果一个函数被标记了@Async注解,调用它的返回值是不是必须用Future。我需要先回忆一下Spring框架中的@Async注解的用法。 首先,@Async注解在Spring中用来实现异步方法调用。当方法被这个注解标记后,它会在单独的线程中执行,这样调用者可以继续执行而不必等待方法完成。关于返回值,我记得有两种情况:如果方法有返回值,通常需要返回Future类型,这样调用方可以通过Future来获取异步执行的结果或处理异常。但如果是void返回类型,可能就不需要Future,因为调用方不需要关心结果。 不过,不确定是否所有返回非void的方法都必须返回Future。可能Spring允许其他类型的返回值,比如CompletableFuture,或者在某些配置下自动包装结果到Future中?或者是否必须显式返回Future实例? 需要确认一下Spring的文档。根据Spring的@Async文档,异步方法可以返回void或者Future。如果返回非Future类型,调用方可能无法正确获取结果,因为方法实际上会在后台执行,但调用方得到的可能是一个立即返回的null或者其他值,这显然不正确。所以,正确的做法是,如果异步方法需要返回结果,应该返回Future,而调用方必须使用Future来接收,以便后续处理。 另外,Spring可能支持返回CompletableFuture,这是Java 8引入的,属于Future的实现,所以在这种情况下,用户可能也可以返回CompletableFuture,而调用方同样用Future来接收。 总结一下,当使用@Async时,如果方法有返回值,应该返回Future类型,调用方必须用Future来接收,以便处理异步结果。如果方法没有返回值,可以返回void,这时候调用方不需要处理Future。可能还需要考虑异常处理的情况,比如Future.get()可能会抛出异常,需要处理ExecutionException等。</think>在 Java 的 Spring 框架中,当方法被 `@Async` 注解标记时,其返回值是否需要使用 `Future` 取决于以下两种情况: --- ### 1. **方法有返回值(需要异步获取结果)** - **必须返回 `Future` 类型**(或其子类,如 `CompletableFuture`)。 Spring 要求异步方法的返回值通过 `Future` 包装,以便调用方能够跟踪异步任务的状态、获取结果或捕获异常。 - **示例**: ```java @Async public Future<String> asyncMethodWithReturn() { // 模拟耗时操作 return new AsyncResult<>("Async Result"); } ``` - **调用方需通过 `Future` 处理结果**: ```java Future<String> future = service.asyncMethodWithReturn(); String result = future.get(); // 阻塞等待结果 ``` --- ### 2. **方法无返回值(仅触发异步执行)** - **返回类型可以是 `void`**,此时调用方无需处理返回值,只需触发异步任务。 - **示例**: ```java @Async public void asyncMethodWithoutReturn() { // 执行后台任务 } ``` --- ### 关键注意事项: - **依赖配置**:需在 Spring 配置中启用异步支持(通过 `@EnableAsync`)。 - **异常处理**:异步方法抛出的异常会封装到 `Future` 中,调用 `future.get()` 时会抛出 `ExecutionException`。 - **返回值限制**:如果异步方法返回非 `Future` 类型,Spring 会直接执行方法,但调用方可能无法正确获取结果(可能导致意外行为)。 --- ### 总结: - **需要结果** → 返回 `Future`,调用方必须使用 `Future` 接收。 - **无需结果** → 返回 `void`,调用方直接触发即可。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值