java8 - fork-join之CompletableFuture 使用总结

CompletableFuture类实现了CompletionStage和Future接口。Future是Java 5添加的类,用来描述一个异步计算的结果,但是获取一个结果时方法较少,要么通过轮询isDone,确认完成后,调用get()获取值,要么调用get()设置一个超时时间。但是这个get()方法会阻塞住调用线程,这种阻塞的方式显然和我们的异步编程的初衷相违背。
为了解决这个问题,JDK吸收了guava的设计思想,加入了Future的诸多扩展功能形成了CompletableFuture。CompletableFuture可以在某个线程完成某任务的时候回调某个函数

CompletableFuture 主要API如下

变换操作

public  CompletionStage thenApply(Functionsuper T,? extends U> fn);
public  CompletionStage thenApplyAsync(Functionsuper T,? extends U> fn);
public  CompletionStage thenApplyAsync(Functionsuper T,? extends U> fn,Executor executor);

例如

public void thenApplay() {
        String result = CompletableFuture.supplyAsync(() -> "hello").thenApply(s -> s + " world").join();
        System.out.println(result);
}

运行结果为

hello world

消耗操作

public CompletionStage thenAccept(Consumersuper T> action);
public CompletionStage thenAcceptAsync(Consumersuper T> action);
public CompletionStage thenAcceptAsync(Consumersuper T> action,Executor executor);

示例

@Test
    public void thenAccept(){
        CompletableFuture.supplyAsync(()->"hello").thenAccept(s-> System.out.println(s+" world"));
    }

运行结果为

hello world

对上一步的计算结果不关心,执行下一个操作

public CompletionStage thenRun(Runnable action);
public CompletionStage thenRunAsync(Runnable action);
public CompletionStage thenRunAsync(Runnable action,Executor executor);

示例

public void thenRun(){
    CompletableFuture.supplyAsync(()->{
        try {
            TimeUnit.SECONDS.sleep(5);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        return "Hello World";
    }).thenRun(()-> System.out.println("Hello World"));
}

运行结果

Hello World

结合两个CompletionStage经过转化后返回

public  CompletionStage thenCombine(CompletionStage other,BiFunctionsuper T,? super U,? extends V> fn);
public  CompletionStage thenCombineAsync(CompletionStage other,BiFunctionsuper T,? super U,? extends V> fn);
public  CompletionStage thenCombineAsync(CompletionStage other,BiFunctionsuper T,? super U,? extends V> fn,Executor executor);

示例

public void thenCombine(){
        String result=CompletableFuture.supplyAsync(()->{
            return "hello ";
        }).thenCombine(CompletableFuture.supplyAsync(()->{
            return "world";
        }),(s1,s2)->s1+s2).join();
        System.out.println(result);
    }

运行结果

hello world

在两个CompletionStage都运行完执行

public CompletionStage runAfterBoth(CompletionStage other,Runnable action);
public CompletionStage runAfterBothAsync(CompletionStage other,Runnable action);
public CompletionStage runAfterBothAsync(CompletionStage other,Runnable action,Executor executor);

示例

public void thenAfterRun() {
    CompletableFuture.supplyAsync(() -> "Hello")
            .runAfterBoth(CompletableFuture.supplyAsync(() -> " World"), () -> System.out.println("Hello World"));
}

运行结果

Hello World

调用优先执行完的结果进行处理

public <U> CompletionStage<U> applyToEither(CompletionStage extends T> other,Functionsuper T, U> fn);
public  CompletionStage applyToEitherAsync(CompletionStage extends T> other,Functionsuper T, U> fn);
public  CompletionStage applyToEitherAsync(CompletionStage extends T> other,Functionsuper T, U> fn,Executor executor);

示例

public void applyToEither(){
        String result=CompletableFuture.supplyAsync(()->"hello").applyToEither(CompletableFuture.supplyAsync(()->" World"),s->s).join();
        System.out.println(result);
    }

运行结果

hello

调用优先执行完的结果进行消耗

这个API与上一个API优点像不同点在于上一个API有返回值

public CompletionStage acceptEither(CompletionStage other,Consumersuper T> action);
public CompletionStage acceptEitherAsync(CompletionStage other,Consumersuper T> action);
public CompletionStage acceptEitherAsync(CompletionStage other,Consumersuper T> action,Executor executor);

示例

public void acceptEither(){
    CompletableFuture.supplyAsync(()->"Hello")
            .acceptEither(CompletableFuture.supplyAsync(()->"World"),System.out::println);
}

运行结果

Hello

只要有一个完成就执行下一步操作

public CompletionStage runAfterEither(CompletionStage other,Runnable action);
public CompletionStage runAfterEitherAsync(CompletionStage other,Runnable action);
public CompletionStage runAfterEitherAsync(CompletionStage other,Runnable action,Executor executor);

示例

public void runAfterEigher() {
    CompletableFuture.supplyAsync(() -> {
        while (true) {
        }
    }).runAfterEither(CompletableFuture.supplyAsync(() -> "s2"), () -> System.out.println("finish"));

运行结果

finish

异常处理

public CompletionStage exceptionally(Function fn);

示例

public void exceptionally() {
        String result = (String) CompletableFuture.supplyAsync(() -> {
            throw new RuntimeException("异常");
        }).exceptionally(e -> {
            System.out.println(e.getMessage());
            return "hello world";
        }).join();
        System.out.println(result);
    }

结果为

java.lang.RuntimeException: 异常
hello world

记录结果

运行完成时,对结果

public CompletionStage whenComplete(BiConsumersuper T, ? super Throwable> action);
public CompletionStage whenCompleteAsync(BiConsumersuper T, ? super Throwable> action);
public CompletionStage whenCompleteAsync(BiConsumersuper T, ? super Throwable> action,Executor executor);

示例

public void whenComplete() {
        String result = CompletableFuture.supplyAsync(() -> {
            try {
                Thread.sleep(3000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            if (1 == 1) {
                throw new RuntimeException("测试一下异常情况");
            }
            return "s1";
        }).whenComplete((s, t) -> {
            System.out.println(s);
            System.out.println(t.getMessage());
        }).exceptionally(e -> {
            System.out.println(e.getMessage());
            return "hello world";
        }).join();
        System.out.println(result);
    }

运行完成时处理结果

public  CompletionStage handle(BiFunctionsuper T, Throwable, ? extends U> fn);
public  CompletionStage handleAsync(BiFunctionsuper T, Throwable, ? extends U> fn);
public  CompletionStage handleAsync(BiFunctionsuper T, Throwable, ? extends U> fn,Executor executor);

示例

public void handle() {
        String result = CompletableFuture.supplyAsync(() -> {
            try {
                Thread.sleep(3000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            //出现异常
            if (1 == 1) {
                throw new RuntimeException("测试一下异常情况");
            }
            return "s1";
        }).handle((s, t) -> {
            if (t != null) {
                return "hello world";
            }
            return s;
        }).join();
        System.out.println(result);
    }

结果为

hello world

你可能感兴趣的:(java,jdk,编程,并发,java)