异步编程六:CompletableFuture异步编程线程串行化

105 阅读2分钟

在CompletableFuture中有以下方法:

public <U> CompletableFuture<U> thenApply(Function<? super T,? extends U> fn)
public <U> CompletableFuture<U> thenApplyAsync(Function<? super T,? extends U> fn)
public <U> CompletableFuture<U> thenApplyAsync(Function<? super T,? extends U> fn, Executor executor)

public CompletableFuture<Void> thenAccept(Consumer<? super T> action)
public CompletableFuture<Void> thenAcceptAsync(Consumer<? super T> action)
public CompletableFuture<Void> thenAcceptAsync(Consumer<? super T> action,Executor executor)

public CompletableFuture<Void> thenRun(Runnable action)
public CompletableFuture<Void> thenRunAsync(Runnable action)
public CompletableFuture<Void> thenRunAsync(Runnable action,Executor executor)
  • thenApply 方法:当一个线程依赖另一个线程时,获取上一个任务返回结果,并返回当前任务的返回值
  • thenAccept方法:消费处理结果,接收任务的处理结果,并消费处理,无返回值
  • thenRun方法:只要上面的任务执行完成,就开始执行thenRun,只是处理完任务后,执行thenRun的后续操作。 thenRun 获取不到上个任务的执行结果,无返回值

thenRun

thenRun 不能获取上一步的执行结果,并无返回值。

public class CompletableFutureWhenThenRun {
    public static void main(String[] args) throws ExecutionException, InterruptedException {
        ExecutorService executor = Executors.newFixedThreadPool(5);

        System.out.println("main start ...");

        CompletableFuture<Void> future = CompletableFuture.supplyAsync(() -> {
            System.out.println("开启异步任务...");
            int i = 10 / 2;
            return i;
        }, executor).thenRun(() -> {
            System.out.println("任务2启动了...");
        });

        System.out.println("获取异步任务返回值:" + future.get());
        System.out.println("main end ...");

        executor.shutdown();
    }
}

执行结果:

main start ...
开启异步任务...
任务2启动了...
获取异步任务返回值:null
main end ...

如果我们需要获取上一步的执行结果,我们使用thenAccept;

thenAccept

消费处理结果,接收任务的处理结果,并消费处理,无返回结果

public class CompletableFutureWhenThenAccept {
    public static void main(String[] args) throws ExecutionException, InterruptedException {
        ExecutorService executor = Executors.newFixedThreadPool(5);

        System.out.println("main start ...");

        CompletableFuture<Void> future = CompletableFuture.supplyAsync(() -> {
            System.out.println("开启异步任务...");
            int i = 10 / 2;
            return i;
        }, executor).thenAcceptAsync((res) -> {
            System.out.println("任务2启动了... 上一步的结果是:" + res);
        }, executor);

        System.out.println("获取异步任务返回值:" + future.get());
        System.out.println("main end ...");

        executor.shutdown();
    }
}

执行结果:

main start ...
开启异步任务...
任务2启动了... 上一步的结果是:5
获取异步任务返回值:null
main end ...

如果我们即需要上一步执行结果,并需要返回值供别人使用,那么我们使用thenApply方法

thenApply

当一个线程依赖另一个线程时,获取上一个任务返回结果,并返回当前任务的返回值

public class CompletableFutureWhenThenApply {
    public static void main(String[] args) throws ExecutionException, InterruptedException {
        ExecutorService executor = Executors.newFixedThreadPool(5);

        System.out.println("main start ...");

        CompletableFuture<Integer> future = CompletableFuture.supplyAsync(() -> {
            System.out.println("开启异步任务...");
            int i = 10 / 2;
            return i;
        }, executor).thenApplyAsync((res) -> {
            System.out.println("任务2启动了... 上一步的结果是:" + res);
            return res * 2;
        }, executor);

        System.out.println("获取异步任务返回值:" + future.get());
        System.out.println("main end ...");

        executor.shutdown();
    }
}

执行结果:

main start ...
开启异步任务...
任务2启动了... 上一步的结果是:5
获取异步任务返回值:10
main end ...