springboot中@Async的简单用法

springboot中@Async的简单用法

文章目录

开启配置

在配置文件或者入口文件上新增注解: @EnableAsync即可

@Async的使用

对应需要异步调用的方法上添加@Async注解即可

无返回值调用

controller代码

java 复制代码
    @RequestMapping("test1")
    public String test1() {
        System.out.println("controller1调用开始");
        testService.test1();
        System.out.println("controller1调用结束");
        return "success test1";
    }

service代码

java 复制代码
    @Async
    public void test1() {
        System.out.println("service1调用开始");
        try {
            Thread.sleep(5000);
        } catch (InterruptedException e) {
            throw new RuntimeException(e);
        }
        System.out.println("service1调用结束");
    }

运行结果

复制代码
controller1调用开始
controller1调用结束
service1调用开始
service1调用结束

可以看到service的已异步调用

带返回值的调用

如果需要执行耗时操作, 又想在结束后执行如发送通知或者保存数据库等方法时, 我们就可以使用带返回值的调用方法

如果需要返回, 则类型需为Future的子类, 最好是返回 CompletableFuture, 里面提供了更多的扩展

controller代码

java 复制代码
    @RequestMapping("test2")
    public String test2() {
        System.out.println("controller2调用开始");
        CompletableFuture<String> stringCompletableFuture = testService.test2();
        stringCompletableFuture.whenComplete((s, throwable) -> {
           if (throwable != null) {
               System.out.println("出现异常: " + throwable.getLocalizedMessage());
               return;
           }
           if (StringUtils.hasText(s)) {
               // todo 此处可以进行发通知/写入数据库等操作
               System.out.println("service2返回值: " + s);
           }
        });
        System.out.println("controller2调用结束");
        return "success test2";
    }

service代码

java 复制代码
    @Async
    public CompletableFuture<String> test2() {
        System.out.println("service2调用开始");
        try {
            Thread.sleep(5000);
        } catch (InterruptedException e) {
            throw new RuntimeException(e);
        }
        System.out.println("service2调用结束");
        return CompletableFuture.completedFuture("成功执行");
    }

运行结果(未生效请重启应用)

复制代码
controller2调用开始
service2调用开始
controller2调用结束
service2调用结束
service2返回值: 成功执行

可以看到service的在异步调用结束后, 执行了 whenComplete里面的内容

如果需要在controlle里面同步执行service, 则调用CompletableFuture.get方法即可

controller代码

java 复制代码
    // service代码不变
    @RequestMapping("test3")
    public String test3() throws ExecutionException, InterruptedException {
        System.out.println("controller3调用开始");
        CompletableFuture<String> stringCompletableFuture = testService.test2();
        String s = stringCompletableFuture.get();
        System.out.println("controller3调用结束, 返回值: " + s);
        return "success test3";
    }

运行结果

复制代码
controller3调用开始
service2调用开始
service2调用结束
controller3调用结束, 返回值: 成功执行

可以看到controller已阻塞等待执行结果, 源码注释也可看出

更多功能请参考CompletableFuture接口, 比如同时调用n个@Async接口并任一执行成功后返回(anyOf)/全部执行成功后返回(allOf)等

相关推荐
异常君3 分钟前
Nginx 架构深度剖析:多进程单线程模型与异步事件驱动
后端·nginx·架构
用户2031196600967 分钟前
空合并运算符
前端·后端
篱笆院的狗7 分钟前
Java 中 ConcurrentHashMap 1.7 和 1.8 之间有哪些区别?
java·开发语言
小奏技术22 分钟前
开源项目看不懂?试试DeepWiki生成任意开源项目实时可对话文档
后端·openai
与秋逐鹿¥28 分钟前
在Mybatis中为什么要同时指定扫描mapper接口和 mapper.xml 文件,理论单独扫描 xml 文件就可以啊
java·tomcat·mybatis
林太白34 分钟前
NestJS企业级登录注册如何做
前端·javascript·后端
cong_37 分钟前
🔥 我的开源项目火了!竟被各个公众号转发
前端·后端·github
异常君39 分钟前
Netty Reactor 线程模型详解:构建高性能网络应用的关键
java·后端·netty
寻月隐君43 分钟前
Rust实战:打造高效字符串分割函数
后端·rust·github
Emma歌小白1 小时前
循环动态地创建多个不同的 DataFrame
后端·python