zoukankan      html  css  js  c++  java
  • 使用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异步调用。

  • 相关阅读:
    SQL查询语句大全集锦
    SQL Union和SQL Union All用法
    SQL Server中替换函数STUFF、replace的使用
    oscache的使用(例子)
    SQL CURSOR 游标 存储过程
    折腾iPhone的生活——AirDrop的使用
    折腾iPhone的生活——通过设置使iPhone更省电
    折腾iPhone的生活——iPhone 5s 开启 assistive touch 后卡顿的问题
    vimium快捷键列表
    在MacOSX下使用Github管理Xcode代码
  • 原文地址:https://www.cnblogs.com/lgjlife/p/10790878.html
Copyright © 2011-2022 走看看