使用CompletableFuture實現異步編程

 

在開發中會碰到一種場景,以下html

Object result1 = service1.func1();//執行80ms
Object result2  =service2.func2();//執行50ms

service3.func3(result1,result2);


func3()須要等待func1和func2的執行結果。總共須要等待130ms.若是可以讓
func1和func2同時執行,那麼最少的等待時間將會是80ms.

java

下面使用CompletableFuture來實現。apache

JDK1.8才新加入的一個實現類CompletableFuture,實現了Future<T>CompletionStage<T>兩個接口。異步

 

定義任務類 async

這裏定義了一個方法findUser,它的返回值是CompletableFuture<String>,用來模擬遠程調用。ide

 

當執行結果是正常時,經過spa

public boolean complete(T value)線程

返回結果。code

 

當執行異常時,若是想向調用者返回異常,經過htm

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異步調用。

相關文章
相關標籤/搜索