首页 > 其他分享 >CompletableFuture实现异步转同步

CompletableFuture实现异步转同步

时间:2023-02-07 15:05:58浏览次数:65  
标签:异步 同步 java get util concurrent CompletableFuture import

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

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

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

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);

    }

}

控制台输出:

20:38:47.648 main 测试开始
20:38:48.654 main 取值: FunTester
20:38:48.654 Thread-1 赋值结束

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

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

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包里面的实现类的代码和逻辑。本人实践,获益匪浅。

标签:异步,同步,java,get,util,concurrent,CompletableFuture,import
From: https://blog.51cto.com/FunTester/6042120

相关文章

  • 63、商城业务---异步---线程池详解
    ......
  • CompletableFuture 捕获异常方式:handle、whenComplete、exceptionally
    使用CompletableFuture编写代码时,异常处理很重要。CompletableFuture提供了三种方法来处理它们:handle()、whenComplete()和exceptionly()。  handle()whenCo......
  • 关于CompletableFuture异步编程使用allof后不继续执行问题
    最近在做异步编程相关工作,将大批量的数据分批次放入异步线程池执行,当每个异步都执行完成之后将结果合并再更新数据库。实例代码如下:intnThreads=5;intunit=quota......
  • Java多线程03——线程安全和线程同步
    1 线程的同步安全1.1线程安全问题设计并发编程的目的是为了使程序获得更高的执行效率,但绝不能出现数据一致性问题。比如多个渠道共同出售电影票,如果没有进行安全控制,就会......
  • Python 异步: 创建和运行异步任务(7)
    您可以从asyncio程序中的协程创建任务对象。任务提供独立调度和运行的协程的句柄,并允许查询、取消任务,以及稍后检索结果和异常。异步事件循环管理任务。因此,所有协程都成......
  • 同步计数器设计与建模
    ⭐本专栏针对FPGA进行入门学习,从数电中常见的逻辑代数讲起,结合VerilogHDL语言学习与仿真,主要对组合逻辑电路与时序逻辑电路进行分析与设计,对状态机FSM进行剖析与建模。......
  • 历史巡检视频和历史巡检轨迹同步
    需求: 如果所示,点击选择任务后会获取对应的历史视频和轨迹回放视频,要做的就是历史视频和轨迹同步,拖动视频进度条轨迹也进行到相应的位置 实现方法:①:首先从后端接口......
  • Android AsyncTask实现异步任务的执行
    Android的AsyncTask比Handler更轻量级一些,适用于简单的异步处理。首先明确Android之所以有Handler和AsyncTask,都是为了不阻塞主线程(UI线程),且UI的更新......
  • ROS多消息同步与多消息回调
    0.存在的问题多传感器数据融合的时候,由于各个传感器采集数据的频率的不同,例如odom50Hz、Imu100Hz、camera25Hz,需要将传感器数据进行时间同步后才能进行融合。这时就需要......
  • 面试官:实现异步的20种方式,你知道几个?
    文章很长,而且持续更新,建议收藏起来,慢慢读!疯狂创客圈总目录博客园版为您奉上珍贵的学习资源:免费赠送:《尼恩Java面试宝典》持续更新+史上最全+面试必备2000页+面......