• 使用CompletableFuture实现异步编程


    在开发中会碰到一种场景,如下

    Object result1 = service1.func1();//执行80ms
    Object result2  =service2.func2();//执行50ms
    
    service3.func3(result1,result2);


    func3()需要等待func1和func2的执行结果。总共需要等待130ms.如果能够让
    func1和func2同时执行,那么最少的等待时间将会是80ms.

    下面使用CompletableFuture来实现。

    JDK1.8才新加入的一个实现类CompletableFuture,实现了Future<T>CompletionStage<T>两个接口。

    定义任务类 

    这里定义了一个方法findUser,它的返回值是CompletableFuture<String>,用来模拟远程调用。

    当执行结果是正常时,通过

    public boolean complete(T value)

    返回结果。

    当执行异常时,如果想向调用者返回异常,通过

    public boolean completeExceptionally(Throwable ex)

    返回异常。

    class TaskService{
    
        public  CompletableFuture<String> findUser(){
            CompletableFuture<String> future = new CompletableFuture();
         //模仿远程调用线程
            new Thread(){
    
                @Override
                public void run() {
    
                    String result = null;
                    System.out.println("任务开始执行....");
                    try{
                        Thread.sleep(3000);
                        //模仿RPC远程调用
                        result = rpcRequest(true);
    
                        System.out.println("任务执行结束....");
    
                    }
                    catch(Exception ex){
                        future.completeExceptionally(ex);
                    }
                    future.complete(result);
                }
            }.start();
         直接返回future.
            return future;
        }
    
        /**
         *功能描述
         * @author lgj
         * @Description   模仿RPC远程调用
         * @date 4/29/19
         * @param:    flag   true:返回正常结果  false:抛出异常
         *    
         * @return:
         *
        */
        public String rpcRequest(boolean flag){
            String result = null;
            if(flag){
                result = "libai";
            }
            else {
                throw new NullPointerException();
            }
            return  result;
        }
    
    
    }     

    主线程调用

    public class CompletableFutureDemo {
    
        public static void main(String args[]){
    
            TaskService service = new TaskService();
    
            CompletableFuture<String> future = service.findUser();
    
            future.whenComplete((t,u)->{
    
                if(u != null){
                    System.out.println("异步调用发生异常:" + u);
                }
                else {
                    System.out.println("异步调用执行正常: " + t);
                }
    
    
            });
    
            System.out.println("主线程任务执行完毕");
    
        }
    }

    主线程通过whenComplete来回调结果。这里需要通过lambada 表达式来获取结果

     public CompletableFuture<T> whenComplete(
            BiConsumer<? super T, ? super Throwable> action) {
            return uniWhenCompleteStage(null, action);
        }

    当结果正常时

    任务开始执行....
    主线程任务执行完毕
    任务执行结束....
    异步调用执行正常: libai

    当调用发生异常时

    任务开始执行....
    主线程任务执行完毕
    异步调用发生异常:java.lang.NullPointerException

    以上,便实现了异步调用。

    目前,dubbo-2.7.0+便是使用CompletableFuture来实现rpc异步调用。

  • 相关阅读:
    Node.js 常用工具 util
    jQuery 选择器
    Node.js 创建HTTP服务器
    Node.js GET/POST请求
    JavaScript 用法
    Node.js 事件
    Node.js 函数
    Bootstrap<基础二> 网格系统
    读文章《Flexbox详解》笔记
    好文要读
  • 原文地址:https://www.cnblogs.com/lgjlife/p/10790878.html
Copyright © 2020-2023  润新知