前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >CompletableFuture实现异步转同步

CompletableFuture实现异步转同步

作者头像
FunTester
发布2023-02-14 16:29:00
1K0
发布2023-02-14 16:29:00
举报
文章被收录于专栏:FunTesterFunTester

在很早之前的文章服务端性能优化之异步查询转同步介绍了一种常用到,服务端开发常用到的多个异步查询转同步的方法,本质上就是利用了java.util.concurrent.CountDownLatch的功能特性,将几个异步查询任务都设置一个java.util.concurrent.CountDownLatch实例,然后等待所有异步任务完成再组装响应,同步返回给客户端。

最近通过对java.util.concurrent包的继续学习,又掌握了java.util.concurrent.CompletableFuture这个类的基本使用,使用场景一个请求过来之后,需要等待另外一个异步任务完成之后,获取响应结果。特别适合WebSocket场景,比如A向B发送了一条消息,需要等待B把消息发过来这种场景。

下面我用一个简单的例子来演示一下java.util.concurrent.CompletableFuture如何使用,先分享一个Java版本:

代码语言:javascript
复制
import com.funtester.frame.SourceCode;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;

import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.TimeoutException;

public class PerFunTest extends SourceCode {

    private static final Logger log = LogManager.getLogger(PerFunTest.class);

    public static void main(String[] args) throws ExecutionException, InterruptedException, TimeoutException {
        log.info("测试开始");
        CompletableFuture<String> future = new CompletableFuture<String>();
        new Thread(() -> {
            sleep(1.0);
            future.complete("FunTester");
            log.info("赋值结束");
        }).start();
        String get = future.get(5, TimeUnit.SECONDS);
        if (get != null) log.info("取值: {}", get);

    }

}

控制台输出:

代码语言:javascript
复制
20:38:47.648 main 测试开始
20:38:48.654 main 取值: FunTester
20:38:48.654 Thread-1 赋值结束

这里我们可以看到47秒测试开始,然后是48秒赋值结束和取值几乎同时完成。如果我们在thread中的sleep时间超过了get超时时间,就会报错。这里可以避免某个异步消息来得太晚导致接口响应时间过长。

下面我展示一下Groovy的实践,可以对比体验一下:

代码语言:javascript
复制
import com.funtester.frame.SourceCode
import groovy.util.logging.Log4j2

import java.util.concurrent.CompletableFuture
import java.util.concurrent.TimeUnit

@Log4j2
class Ts extends SourceCode {

    static void main(String[] args) {
        log.info("测试开始")
        def future = new CompletableFuture<String>()
        fun {
            sleep(1.0)
            future.complete("FunTester")
            log.info("赋值结束")
        }
        def get = future.get(5, TimeUnit.SECONDS)
        if (get != null) log.info("取值: $get")
    }
}

对于异步转同步的场景实践,就分享到这里。对于对Java多线程编程有兴趣的小伙伴,可以多看java.util.concurrent包里面的实现类的代码和逻辑。本人实践,获益匪浅。

FunTester原创专题推荐~

-- By FunTester

本文参与 腾讯云自媒体分享计划,分享自微信公众号。
原始发表:2023-02-07,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 FunTester 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档