Lambda从入门到精通之三十六 CompletableFuture异步编程 get方法使用详解

CompletableFuture经过复杂计算后,对多个计算任务计算后,可以通过lambda的收集器收集结果,例如xxx.collect(Collectors.toList())。
我们也可以使用for循环调用CompletableFuture的get方法来逐个获取,或者如果计算任务本身就只有一个计算任务,那么就可以直接用get方法来获取结果。
CompletableFuture提供的get的3个方法:

T get() 
T get(long timeout, TimeUnit unit) 
T getNow(T valueIfAbsent) 

同时还提供了这两个方法,可以修改返回结果

boolean complete(T value) 
void obtrudeValue(T value) 

我们看demo:

import java.util.concurrent.CompletableFuture;
import java.util.concurrent.TimeUnit;

/**
 * 使用CompletableFuture异步编程 get
 * @author www.itzhimei.com
 */
public class FutureTest_13 {

    public static void main(String[] args) throws Exception {

        //getNow时没有返回结果则返回给定的结果
        String join1 = CompletableFuture.supplyAsync(() -> FutureTest_13.getTaskResult(1000, "Test Task 1"))
                .getNow("备选结果");
        System.out.println(join1);
        /* 输出
        备选结果
         */


        //get结果一直等待结果返回
        String join2 = CompletableFuture.supplyAsync(() -> FutureTest_13.getTaskResult(1000, "Test Task 2"))
                .get();
        System.out.println(join2);
        /* 输出
        Test Task 2
         */


        //get结果,并指定给定等待时间,超时则报错TimeoutException
        String join3 = CompletableFuture.supplyAsync(() -> FutureTest_13.getTaskResult(10000, "Test Task 3"))
                .get(2,  TimeUnit.SECONDS);
        System.out.println(join3);
        /* 输出
        Exception in thread "main" java.util.concurrent.TimeoutException
            at java.util.concurrent.CompletableFuture.timedAwaitDone(CompletableFuture.java:365)
            at java.util.concurrent.CompletableFuture.get(CompletableFuture.java:2260)
            at com.itzhimei.base.lambda.future.FutureTest_13.main(FutureTest_13.java:32)
         */


        //obtrudeValue手动指定计算结果不管任务是否计算完成
        CompletableFuture<String> join4CompletableFuture = CompletableFuture.supplyAsync(() -> FutureTest_13.getTaskResult(10000, "Test Task 4"));
        join4CompletableFuture.obtrudeValue("手动指定返回结果");
        System.out.println(join4CompletableFuture.get());

        
        //complete判断是否计算完成,如果没有则直接将结果修改为指定的结果
        CompletableFuture<String> t1 = CompletableFuture.supplyAsync(() -> FutureTest_13.getTaskResult(10000, "Test Task 1"));
        boolean manualComplete = t1.complete("手动complete");
        System.out.println(manualComplete);
        System.out.println(t1.get());
        /*
        true
        手动complete
         */

    }

    public static String getTaskResult(long sleepTime, String task) {
        try {
            Thread.sleep(sleepTime);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        return task;
    }

}

/* 输出
备选结果
Test Task 2
Exception in thread "main" java.util.concurrent.TimeoutException
	at java.util.concurrent.CompletableFuture.timedAwaitDone(CompletableFuture.java:365)
	at java.util.concurrent.CompletableFuture.get(CompletableFuture.java:2260)
	at com.itzhimei.base.lambda.future.FutureTest_13.main(FutureTest_13.java:26)

手动指定返回结果

true
手动complete

 */