首页 > 其他分享 >Future and CompletableFuture

Future and CompletableFuture

时间:2022-08-28 16:55:41浏览次数:43  
标签:异步 return get future CompletableFuture Future

 

Future代表异步执行的结果,也就是说异步执行完毕后,结果保存在Future里, 我们在使用线程池submit()时需要传入Callable接口,线程池的返回值为一个Future,而Future则保存了执行的结果 ,可通过Future的get()方法取出结果,如果线程池使用的是execute(),则传入的是Runnable接口 无返回值。

复制代码
    /**
     * submit返回值为Future,
     * @param num
     * @return
     */
    public static Future<?> futureTask(Integer num) {
        return executorService.submit(new Callable<Object>() {
            @Override
            public Object call() throws Exception {
                return getMemberStatusRpcApi(num);
            }
        });
    }

     /**
     * execute无返回值,因为参数是Runnable
     */
    public static void noResult(Integer num){
        executorService.execute(new Runnable() {
            @Override
            public void run() {
                getMemberStatusRpcApi(num);
            }
        });
    }
复制代码

获取异步执行结果使用get(),isDone判断异步执行是否结束

 Future<?> future = futureTask(20);
   if (future.isDone()){
      System.out.println(future.get());
   }

cancel(),取消异步执行

 Future<?> future = futureTask(20);
 future.cancel(true);

get(long time , TimeUnit time),在指定时间内获取执行结果,如果超过时间还没获取到结果,则报超时异常

  Future<?> future = futureTask(20);
  future.get(3,TimeUnit.SECONDS);

isCancelled(),判断任务是否取消

  boolean cancelled = future.isCancelled();

execute()和submit区别

1.execute无返回值,这样就无法知道任务是否执行成功

2.execute抛出异常后无法处理,不能捕捉异常,而submit可以捕获异常;

Future不足之处

虽然Future在执行多个操作时的确做到了异步,但是Future.get()取出异步执行结果的时候缺是阻塞的, 只有当前一个操作get完以后才能到下一个操作get 

 

 

CompletableFuture

1:当我们系统中某个接口需要调用多个接口,如果我们使用同步的方式去调用,那么只有等一个接口调用完毕后再到下一个接口继续调用,如果这些任务不耗时,其实是完全能接受的,但是如果调用的这些接口耗时,用同步的方式去调用其实是不明智的做法。 如图,我们系统需要用RPC远程去调用A,B,C,D四个系统的接口,每个接口耗时100ms,那么总共就是400ms 

 

 

我们能不能想其它的方法来缩短时间呢?当然可以,譬如使用消息队列,在这里我们先不讨论中间件,而是直接使用java类库,Java8引入了CompletableFuture,使用它可以进行完美的异步操作,我们看下使用它后的示意图。 可以看出,使用CompletableFuture是异步调用的,等到大家都调用结束后,再对结果进行汇总 

code

复制代码
private static CompletableFuture<Integer> test1() throws InterruptedException {
        return CompletableFuture.supplyAsync(() -> {
            try {
                Thread.sleep(2000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            return 1;
        });
    }

    private static CompletableFuture<Integer> test2() throws InterruptedException {

        return CompletableFuture.supplyAsync(() -> {
            try {
                Thread.sleep(2000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            return 2;
        });
    }

    private static CompletableFuture<Integer> test3() throws InterruptedException {
        return CompletableFuture.supplyAsync(() -> {
            try {
                Thread.sleep(2000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            return 3;
        });
    }
    
    /**
     *如下代码,我们要计算三个接口的返回值进行汇总,每个接口耗时两秒,同步执行
     *需要消耗6秒,使用Completable后只需要2秒, anyOff是将多个执行完毕的
     *CompletableFuture进行计算
     *
     */
    private static CompletableFuture<Integer> solution() throws InterruptedException {
        CompletableFuture<Integer> test1 = test1();
        CompletableFuture<Integer> test2 = test2();
        CompletableFuture<Integer> test3 = test3();
        return CompletableFuture
                .anyOf(test1,test2,test3)
                .thenApply(v -> {
                    Integer i = 0;
                    try {
                        Integer integer = test1.get();
                        Integer integer1 = test2.get();
                        Integer integer2 = test3.get();
                        i = integer + integer1 + integer2;
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    } catch (ExecutionException e) {
                        e.printStackTrace();
                    }
                    return i;
                });
    }
复制代码

标签:异步,return,get,future,CompletableFuture,Future
From: https://www.cnblogs.com/Bkxk/p/16633071.html

相关文章

  • CompletableFuture的简单使用
    日常开发中,我们都会用到线程池,一般会用execute()和submit()方法提交任务。但是当你用过CompletableFuture之后,就会发现以前的线程池处理任务有多难用,功能有多简陋,Completab......
  • 4.Future对象
    asyncio.Future对象Future是Task类的基类Task对象内部await结果的处理是基于Future对象来的asyncdefmain():#获取当前事件循环loop=asyncio.get_runni......
  • 【python error】FutureWarning: The error_bad_lines argument has been deprecated
    前言博主运行python代码的时候出现了warning,主要是模块版本引起的。drawlog.py  warningdrawlog.py:76:FutureWarning:Theerror_bad_linesargumenthasbeend......
  • 奇淫巧技,CompletableFuture 异步多线程是真的优雅
     一个示例回顾Future一些业务场景我们需要使用多线程异步执行任务,加快任务执行速度。JDK5新增了Future接口,用于描述一个异步计算的结果。虽然Future以及相关使用......