SpringBoot异步调用

本文详细介绍了Java中的异步调用原理及其实现,通过一个Demo展示了如何使用@EnableAsync注解、@Async注解以及Future来实现异步方法。文中还解释了Future接口的作用,并给出了在获取异步方法返回值时的注意事项,强调了异步方法与同步方法的区别。同时,文章指出了导致@Async失效的一些常见错误,帮助开发者避免在实际应用中遇到问题。

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

什么是异步调用

方法调用默认是同步的,同步就是指方法必须一行一行的往下面执行,需要等待上一行代码执行完后才能执行下面的代码,而异步调用则是不需要等待上一行代码执行完后,就可以立即执行。

使用场景

当我们的代码不需要考虑事物时,并且也不需要即时响应,这时候我们可以选择使用异步调用来减少程序的相应时间。比如注册时发送确认邮件通知、写入日志等场景

下面我们将以demo的形式来完成异步调用。

一、启动类上加注解

import org.springframework.scheduling.annotation.EnableAsync;

@EnableAsync

二、编写异步类

import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Component;

@Component
public class AsyncTask {
    @Async
    public String task(){
        System.out.println("异步任务");
        return "ok";
    }
}

三、编写测试类

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

@RestController
public class TestController {
    @Autowired
    private AsyncTask asyncTask;

    @RequestMapping("/test")
    public void test(){
        String content=asyncTask.task();
        System.out.println(content);
        System.out.println("主程序");
    }
}

测试之后输出

null
主程序
异步任务

我们会发现拿到的返回值是null,所以不能够拿到异步调用的返回值,并且异步的方法也是在主程序执行完之后再去执行的。

那么应该如何监听是否执行完并拿到返回值呢,下面将解决这个问题。

修改异步类

@Async
public Future<String> task(){
    System.out.println("异步任务");
    return new AsyncResult<String>("执行完毕");
}

修改测试类

@RequestMapping("/test")
public void test() throws ExecutionException, InterruptedException {
    Future<String> future =asyncTask.task();

    while (true){
        if(future.isDone()){
            System.out.println( future.get());
            break;
        }
    }
    System.out.println("主程序");
}

测试之后会输出

异步任务
执行完毕
主程序

说明我们已经解决了这个问题。

这里我们用到了Future,下面我介绍下这个Future:

Future是对于具体的Runnable或者Callable任务的执行结果进行取消、查询是否完成、获取结果的接口。必要时可以通过get方法获取执行结果,该方法会阻塞直到任务返回结果。

他有这些方法

  • cancel(boolean mayInterruptIfRunning):用来取消任务,该方法有以下几种场景:

    ​ 任务还没有被执行:参数不管为true还是false则会被取消,并且返回true。

    ​ 任务已经执行完成:参数不管为true还是false则不会被取消,并且返回false。

    ​ 任务已经执行但还没有执行完毕:参数为true则会取消,并且返回true,参数为false则不会取消,并且返回false

  • isCancelled():表示任务是否被取消成功。

  • isDone():表示是否执行完成

  • get():获取执行结果,这个方法会产生阻塞,会一直等到任务执行完毕才返回。

  • get(long timeout, TimeUnit unit):获取执行结果,如果在指定时间内没有获取到结果,则返回null。

注意事项

如下方式会使@Async失效

  1. 异步方法使用static修饰
  2. 异步类没有使用@Component注解(或其他注解)导致spring无法扫描到异步类
  3. 异步方法不能与调用异步方法的方法在同一个类中
  4. 类中需要使用@Autowired或@Resource等注解自动注入,不能自己手动new对象
  5. 如果使用SpringBoot框架必须在启动类中增加@EnableAsync注解
  6. 在Async 方法上标注@Transactional是没用的。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值