1、前言
学习java基础时候多线程使用我们首先学习的 Runable
、Future
、 Thread
、ExecutorService
、Callable
等相关类,在我们日常工作或者学习中有些场景并不满足我们需求,JDK8引入了一个新的类 CompletableFuture
来解决之前得问题, CompletableFuture
实现了 Future
接口和 CompletionStage
。因此 CompletableFuture是对 Futrue的功能增强包含了Future的功能。从继承的另一个 CompletionStage
的名称来看完成阶段性的接口,接下来了解一下 CompletableFuture
的一些基本情况以及使用和注意事项。
2、CompletableFuture使用
CompletableFuture提供了几十种方法,辅助我们的异步任务场景。这些方法包括创建异步任务、任务异步回调、多个任务组合处理等方面,JDK8设计出CompletableFuture。CompletableFuture提供了一种观察者模式类似的机制,可以让任务执行完成后通知监听的一方。
自定义线城池,一下代码都会使用到
static ExecutorService executor = Executors.newFixedThreadPool(3, new ThreadFactory() {
int count = 1;
@Override
public Thread newThread(Runnable runnable) {
return new Thread(runnable, "completableFuture-executor-" + count++);
}
});
2.1创建异步任务
runAsync 用于构建一个没有入参也没有出参的任务;
supplyAsync 用于构建一个没有入参但是有出参的任务
runAsync和supplyAsync可以指定线程池,如果不指定,则使用ForkJoinPool的commonPool线程池
先看源码
public static CompletableFuture supplyAsync(Supplier supplier) {
return asyncSupplyStage(asyncPool, supplier);
}
public static CompletableFuture supplyAsync(Supplier supplier,
Executor executor) {
return asyncSupplyStage(screenExecutor(executor), supplier);
}
public static CompletableFuture runAsync(Runnable runnable) {
return asyncRunStage(asyncPool, runnable);
}
public static CompletableFuture runAsync(Runnable runnable,
Executor executor) {
return asyncRunStage(screenExecutor(executor), runnable);
}
runAsync执行CompletableFuture任务,没有返回值。
/**
* runAsync执行CompletableFuture任务,没有返回值。
*/
public static void runAsyncExample() throws ExecutionException, InterruptedException {
CompletableFuture completableFuture = CompletableFuture.runAsync(() -> {
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("异步线程执行执行结束");
});
System.out.println("异步线程执行状态" + completableFuture.isDone());
System.out.println("主线程正在执行");
System.out.println("异步线程执行状态" + completableFuture.isDone());
System.out.println(completableFuture.get());
}
执行结果
异步线程执行状态false
completableFuture-当前线程名称:ForkJoinPool.commonPool-worker-9
异步线程执行执行结束
null
supplyAsync执行CompletableFuture任务,支持返回值-使用自定义线城池
public static void supplyAsyncExample() throws ExecutionException, InterruptedException {
CompletableFuture completableFuture = CompletableFuture.supplyAsync(() -> {
try {
Thread.sleep(1001);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("completableFuture2-当前线程名称:" + Thread.currentThread().getName());
System.out.println("异步线程执行执行结束");
return "msg-异步线程执行结束";
}, executor);
System.out.println("主线程-------supplyAsyncExample-----正在执行");
System.out.println(completableFuture.join());
executor.shutdown(); // 线程池需要关闭
}
执行结果
主线程-------supplyAsyncExample-----正在执行
completableFuture2-当前线程名称:completableFuture-executor-1
异步线程执行执行结束
msg-异步线程执行结束
2.2任务异步回调
2.2.1 thenRun/thenRunAsync
不关心上一个任务的执行返回结果,无参数,无返回值
CompletableFuture的thenRun方法,通俗点讲就是,做完第一个任务后,再做第二个任务。某个任务执行完成后,执行回调方法;但是前后两个任务没有参数传递,第二个任务也没有返回值
如果你执行第一个任务的时候,传入了一个自定义线程池:
public CompletableFuture thenRun(Runnable action);
public CompletableFuture thenRunAsync(Runnable action);
thenRun代码
public static void thenRunExample() throws ExecutionException, InterruptedException {
CompletableFuture completableFuture = CompletableFuture.supplyAsync(() -> {
try {
Thread.sleep(1001);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("异步线程执行执行结束,当前线程"+Thread.currentThread().getName());
return "msg-异步线程执行结束";
}, executor);
System.out.println("主线程-------thenRunExample-----正在执行1");
CompletableFuture voidCompletableFuture = completableFuture.thenRun(() -> {
System.out.println("thenRunExample----正在执行第二个任务,当前线程"+Thread.currentThread().getName());
});
System.out.println("主线程-------thenRunExample-----正在执行2");
System.out.println(voidCompletableFuture.get());
executor.shutdown(); // 线程池需要关闭
}
执行结果
主线程-------thenRunExample-----正在执行1
主线程-------thenRunExample-----正在执行2
异步线程执行执行结束,当前线程completableFuture-executor-1
thenRunExample----正在执行第二个任务,当前线程completableFuture-executor-1
null
thenRunAsync代码-异步使用自定义线城池
public static void thenRunAsyncExample() throws ExecutionException, InterruptedException {
CompletableFuture completableFuture = CompletableFuture.supplyAsync(() -> {
try {
Thread.sleep(1001);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("异步线程执行执行结束---当前线城"+Thread.currentThread().getName());
return "msg-异步线程执行结束";
}, executor);
System.out.println("主线程-------thenRunAsyncExample-----正在执行1");
CompletableFuture voidCompletableFuture = completableFuture.thenRunAsync(() -> {
System.out.println("thenRunExample----正在执行第二个任务---当前线城"+Thread.currentThread().getName());
});
System.out.println("主线程-------thenRunAsyncExample-----正在执行2");
System.out.println(voidCompletableFuture.get());
executor.shutdown(); // 线程池需要关闭
}
执行结果
主线程-------thenRunAsyncExample-----正在执行1
主线程-------thenRunAsyncExample-----正在执行2
异步线程执行执行结束---当前线城completableFuture-executor-1
thenRunExample----正在执行第二个任务---当前线城ForkJoinPool.commonPool-worker-9
null
2.2.2.thenAccept/thenAcceptAsync
第一个任务执行完成后,执行第二个回调方法任务,会将该任务的执行结果,作为入参,传递到回调方法中,但是回调方法是没有返回值的。
thenAccept代码示例
public static void thenAcceptExample() throws ExecutionException, InterruptedException {
CompletableFuture completableFuture = CompletableFuture.supplyAsync(() -> {
try {
Thread.sleep(1001);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("异步线程执行执行结束--执行线程" + Thread.currentThread().getName());
return "msg-异步线程执行结束";
}, executor);
System.out.println("主线程-------thenAcceptExample-----正在执行1");
CompletableFuture voidCompletableFuture = completableFuture.thenAccept((msg) -> {
System.out.println("thenAccept接受上一步返回参数" + msg);
System.out.println("thenAcceptExample----正在执行第二个任务--执行线程" + Thread.currentThread().getName());
});
System.out.println("主线程-------thenAcceptExample-----正在执行2");
System.out.println(voidCompletableFuture.get());
executor.shutdown(); // 线程池需要关闭
}
执行结果
主线程-------thenAcceptExample-----正在执行1
主线程-------thenAcceptExample-----正在执行2
异步线程执行执行结束--执行线程completableFuture-executor-1
thenAccept接受上一步返回参数msg-异步线程执行结束
thenAcceptExample----正在执行第二个任务--执行线程completableFuture-executor-1
null
thenAcceptAsync代码示例
public static void thenAcceptAsyncExample() throws ExecutionException, InterruptedException {
CompletableFuture completableFuture = CompletableFuture.supplyAsync(() -> {
try {
Thread.sleep(1001);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("异步线程执行执行结束---执行线程" + Thread.currentThread().getName());
return "msg-异步线程执行结束";
}, executor);
System.out.println("主线程-------thenAcceptExample-----正在执行1");
CompletableFuture voidCompletableFuture = completableFuture.thenAcceptAsync((msg) -> {
System.out.println("thenAccept接受上一步返回参数" + msg);
System.out.println("thenAcceptExample----正在执行第二个任务---执行线程" + Thread.currentThread().getName());
}, executor);
System.out.println("主线程-------thenAcceptExample-----正在执行2");
System.out.println(voidCompletableFuture.get());
executor.shutdown(); // 线程池需要关闭
}
运行结果
主线程-------thenAcceptExample-----正在执行1
主线程-------thenAcceptExample-----正在执行2
异步线程执行执行结束---执行线程completableFuture-executor-1
thenAccept接受上一步返回参数msg-异步线程执行结束
thenAcceptExample----正在执行第二个任务---执行线程completableFuture-executor-2
null
第一个任务执行完成后,执行第二个回调方法任务,会将该任务的执行结果,作为入参,传递到回调方法中,并且回调方法是有返回值的
thenApply-不关心上一个任务的执行返回结果,有参数,有返回值-
代码
public static void thenApplyExample() throws ExecutionException, InterruptedException {
CompletableFuture completableFuture = CompletableFuture.supplyAsync(() -> {
try {
Thread.sleep(1001);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("异步线程执行执行结束---当前线程"+ Thread.currentThread().getName());
return "msg-异步线程执行结束";
}, executor);
System.out.println("主线程-------thenApplyExample-----正在执行1");
CompletableFuture voidCompletableFuture = completableFuture.thenApply((msg) -> {
System.out.println("thenApply接受上一步返回参数" + msg);
System.out.println("thenApplyExample----正在执行第二个任务----当前线程"+ Thread.currentThread().getName());
return "thenApplyExample执行任务结束";
});
System.out.println("主线程-------thenApplyExample-----正在执行2");
System.out.println(voidCompletableFuture.get());
executor.shutdown(); // 线池需要关闭
}
执行结果
主线程-------thenApplyExample-----正在执行1
主线程-------thenApplyExample-----正在执行2
异步线程执行执行结束---当前线程completableFuture-executor-1
thenApply接受上一步返回参数msg-异步线程执行结束
thenApplyExample----正在执行第二个任务----当前线程completableFuture-executor-1
thenApplyExample执行任务结束
thenApplyAsync-任务异步回调-不关心上一个任务的执行返回结果,有参数,有返回值-
public static void thenApplyAsyncExample() throws ExecutionException, InterruptedException {
CompletableFuture completableFuture = CompletableFuture.supplyAsync(() -> {
try {
Thread.sleep(1001);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("异步线程执行执行结束");
System.out.println("当前线程名称:" + Thread.currentThread().getName());
return "msg-异步线程执行结束";
}, executor);
System.out.println("主线程-------thenApplyAsyncExample-----正在执行1");
CompletableFuture voidCompletableFuture = completableFuture.thenApplyAsync((msg) -> {
System.out.println("thenApply接受上一步返回参数" + msg);
System.out.println("当前线程名称:" + Thread.currentThread().getName());
System.out.println("thenApplyAsyncExample----正在执行第二个任务");
return "thenApplyAsyncExample执行任务结束";
});
System.out.println("主线程-------thenApplyAsyncExample-----正在执行2");
System.out.println(voidCompletableFuture.get());
executor.shutdown(); // 线池需要关闭
}
执行结果
主线程-------thenApplyAsyncExample-----正在执行1
主线程-------thenApplyAsyncExample-----正在执行2
异步线程执行执行结束
当前线程名称:completableFuture-executor-1
thenApply接受上一步返回参数msg-异步线程执行结束
当前线程名称:ForkJoinPool.commonPool-worker-9
thenApplyAsyncExample----正在执行第二个任务
thenApplyAsyncExample执行任务结束
2.2.4 exceptionally-
某个任务执行异常时,执行的回调方法;并且有抛出异常作为参数,传递到回调方法。
执行代码
public static void exceptionallyExample() throws ExecutionException, InterruptedException {
CompletableFuture completableFuture = CompletableFuture.supplyAsync(() -> {
try {
Thread.sleep(1001);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("当前线程名称:" + Thread.currentThread().getName());
throw new RuntimeException("咳咳!执行异常啦");
}, executor);
System.out.println("主线程-------exceptionallyExample-----正在执行1");
CompletableFuture voidCompletableFuture = completableFuture.exceptionally((throwable) -> {
System.out.println("当前线程名称:" + Thread.currentThread().getName());
System.out.println("exceptionallyExample----发生异常信息----" + throwable.getMessage());
return "handleExample执行结束";
});
System.out.println("主线程-------exceptionallyExample-----正在执行2");
System.out.println(voidCompletableFuture.get());
executor.shutdown(); // 线池需关闭
}
执行结果
主线程-------exceptionallyExample-----正在执行1
主线程-------exceptionallyExample-----正在执行2
当前线程名称:completableFuture-executor-1
当前线程名称:completableFuture-executor-1
exceptionallyExample----发生异常信息----java.lang.RuntimeException: 咳咳!执行异常啦
handleExample执行结束
2.2.5whenComplete/handle
whenComplete:某个任务执行完成后,执行的回调方法,无返回值;并且whenComplete方法返回的CompletableFuture的result是上个任务的结果。
handle:任务执行完成后,执行回调方法,并且是有返回值的;并且handle方法返回的CompletableFuture的result是回调方法执行的结果。
whenComplete 代码示例
public static void whenCompleteExample() throws ExecutionException, InterruptedException {
CompletableFuture completableFuture = CompletableFuture.supplyAsync(() -> {
try {
Thread.sleep(1001);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("异步线程执行执行结束--当前线程名称:" + Thread.currentThread().getName());
return "msg-异步线程执行结束666";
}, executor);
System.out.println("主线程-------whenCompleteExample-----正在执行1");
CompletableFuture voidCompletableFuture = completableFuture.whenComplete((msg, throwable) -> {
System.out.println("当前线程名称:" + Thread.currentThread().getName());
System.out.println("whenCompleteExample----接受参数" + msg);
});
System.out.println("主线程-------whenCompleteExample-----正在执行2");
System.out.println(voidCompletableFuture.get());
executor.shutdown(); // 线池需要关闭
}
执行结果
主线程-------whenCompleteExample-----正在执行1
主线程-------whenCompleteExample-----正在执行2
异步线程执行执行结束--当前线程名称:completableFuture-executor-1
当前线程名称:completableFuture-executor-1
whenCompleteExample----接受参数msg-异步线程执行结束666
msg-异步线程执行结束666
Handle 代码示例
public static void handleExample() throws ExecutionException, InterruptedException {
CompletableFuture completableFuture = CompletableFuture.supplyAsync(() -> {
try {
Thread.sleep(1001);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("异步线程执行执行结束");
System.out.println("当前线程名称:" + Thread.currentThread().getName());
return "msg-异步线程执行结束666";
}, executor);
System.out.println("主线程-------handleExample-----正在执行1");
CompletableFuture voidCompletableFuture = completableFuture.handle((msg, throwable) -> {
System.out.println("当前线程名称:" + Thread.currentThread().getName());
System.out.println("handleExample----接受参数" + msg);
return "handleExample执行结束";
});
System.out.println("主线程-------handleExample-----正在执行2");
System.out.println(voidCompletableFuture.get());
executor.shutdown(); // 线池需要关闭
}
执行结果
主线程-------handleExample-----正在执行1
主线程-------handleExample-----正在执行2
异步线程执行执行结束
当前线程名称:completableFuture-executor-1
当前线程名称:completableFuture-executor-1
handleExample----接受参数msg-异步线程执行结束666
handleExample执行结束
2.3 多个任务组合处理
2.3.1 thenCombine / thenAcceptBoth / runAfterBoth----AND组合关系
将两个CompletableFuture组合起来,只有这两个都正常执行完了,才会执行某个任务。
区别在于:
thenCombine:会将两个任务的执行结果作为方法入参,传递到指定方法中,且有返回值
thenAcceptBoth: 会将两个任务的执行结果作为方法入参,传递到指定方法中,且无返回值
runAfterBoth 不会把执行结果当做方法入参,且没有返回值。
thenCombine代码示列
public static void thenCombineExample() throws ExecutionException, InterruptedException {
CompletableFuture completableFuture1 = CompletableFuture.supplyAsync(() -> {
try {
Thread.sleep(1001);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("completableFuture1-当前线程名称:" + Thread.currentThread().getName());
return "当前线程1执行结束";
}, executor);
CompletableFuture completableFuture2 = CompletableFuture.supplyAsync(() -> {
try {
Thread.sleep(1001);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("completableFuture2-当前线程名称:" + Thread.currentThread().getName());
return "当前线程2执行结束";
}, executor).thenCombine(completableFuture1, (msg1, msg2) -> {
System.out.println("completableFuture1返回结果----" + msg1);
System.out.println("completableFuture2返回结果----" + msg2);
return "所有线程执行结束";
});
System.out.println("主线程-------thenCombineExample-----正在执行2");
System.out.println(completableFuture2.join());
executor.shutdown(); // 线池需关闭
}
执行结果
主线程-------thenCombineExample-----正在执行2
completableFuture1-当前线程名称:completableFuture-executor-1
completableFuture2-当前线程名称:completableFuture-executor-2
completableFuture1返回结果----当前线程2执行结束
completableFuture2返回结果----当前线程1执行结束
所有线程执行结束
thenAcceptBoth代码示例
public static void thenAcceptBothExample() throws ExecutionException, InterruptedException {
CompletableFuture completableFuture1 = CompletableFuture.supplyAsync(() -> {
try {
Thread.sleep(1001);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("completableFuture1-当前线程名称:" + Thread.currentThread().getName());
return "当前线程1执行结束";
});
CompletableFuture completableFuture2 = CompletableFuture.supplyAsync(() -> {
try {
Thread.sleep(1001);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("completableFuture2-当前线程名称:" + Thread.currentThread().getName());
return "当前线程2执行结束";
}).thenAcceptBoth(completableFuture1, (msg1, msg2) -> {
System.out.println("completableFuture1返回结果----" + msg1);
System.out.println("completableFuture2返回结果----" + msg2);
});
System.out.println("主线程-------thenAcceptBothExample-----正在执行2");
System.out.println(completableFuture2.join());
executor.shutdown(); // 线池需关闭
}
运行结果
主线程-------thenAcceptBothExample-----正在执行2
completableFuture1-当前线程名称:ForkJoinPool.commonPool-worker-9
completableFuture2-当前线程名称:ForkJoinPool.commonPool-worker-2
completableFuture1返回结果----当前线程2执行结束
completableFuture2返回结果----当前线程1执行结束
null
runAfterBoth代码示例
public static void runAfterBothExample() throws ExecutionException, InterruptedException {
CompletableFuture completableFuture1 = CompletableFuture.supplyAsync(() -> {
try {
Thread.sleep(1001);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("completableFuture1-当前线程名称:" + Thread.currentThread().getName());
return "当前线程1执行结束";
});
CompletableFuture completableFuture2 = CompletableFuture.supplyAsync(() -> {
try {
Thread.sleep(1001);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("completableFuture2-当前线程名称:" + Thread.currentThread().getName());
return "当前线程2执行结束";
}).runAfterBoth(completableFuture1, () -> {
System.out.println("两个线程都执行结束啦----");
});
System.out.println("主线程-------runAfterBothExample-----正在执行2");
System.out.println(completableFuture2.join());
executor.shutdown(); // 线池需关闭
}
运行结果
主线程-------runAfterBothExample-----正在执行2
completableFuture2-当前线程名称:ForkJoinPool.commonPool-worker-2
completableFuture1-当前线程名称:ForkJoinPool.commonPool-worker-9
两个线程都执行结束啦----
null
2.3.2 applyToEither / acceptEither / runAfterEither ----OR组合关系
将两个CompletableFuture组合起来,只要其中一个执行完了,就会执行某个任务。
区别在于:
applyToEither代码示例
public static void applyToEitherExample() throws ExecutionException, InterruptedException {
CompletableFuture completableFuture1 = CompletableFuture.supplyAsync(() -> {
try {
Thread.sleep(101);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("completableFuture1-当前线程名称:" + Thread.currentThread().getName());
return "当前线程1执行结束";
});
CompletableFuture completableFuture2 = CompletableFuture.supplyAsync(() -> {
try {
Thread.sleep(10001);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("completableFuture2-当前线程名称:" + Thread.currentThread().getName());
return "当前线程2执行结束";
}).applyToEither(completableFuture1, msg -> {
return msg;
});
System.out.println("主线程-------thenCombineExample-----正在执行2");
System.out.println(completableFuture2.join());
executor.shutdown(); // 线池需关闭
}
执行结果
主线程-------thenCombineExample-----正在执行2
completableFuture1-当前线程名称:ForkJoinPool.commonPool-worker-9
当前线程1执行结束
acceptEither代码示例
public static void acceptEitherExample() throws ExecutionException, InterruptedException {
CompletableFuture completableFuture1 = CompletableFuture.supplyAsync(() -> {
try {
Thread.sleep(1001);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("completableFuture1-当前线程名称:" + Thread.currentThread().getName());
return "当前线程1执行结束";
});
CompletableFuture completableFuture2 = CompletableFuture.supplyAsync(() -> {
try {
Thread.sleep(10001);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("completableFuture2-当前线程名称:" + Thread.currentThread().getName());
return "当前线程2执行结束";
}).acceptEither(completableFuture1, msg -> {
System.out.println("获取某线程返回参数------" + msg);
});
System.out.println("主线程-------acceptEitherExample-----正在执行2");
System.out.println(completableFuture2.join());
executor.shutdown(); // 线池需关闭
}
执行结果
主线程-------acceptEitherExample-----正在执行2
completableFuture1-当前线程名称:ForkJoinPool.commonPool-worker-9
获取某线程返回参数------当前线程1执行结束
null
2.3.3AllOf/AnyOf 多个任务组合处理
3AllOf:所有任务都执行完成后,才执行 allOf返回的CompletableFuture。如果任意一个任务异常,allOf的CompletableFuture,执行get方法,会抛出异常
AnyOf:任意一个任务执行完,就执行anyOf返回的CompletableFuture。如果执行的任务异常,anyOf的CompletableFuture,执行get方法,会抛出异常
AllOf代码示例
/**
* 多个任务组合处理
* 所有任务都执行完成后,才执行 allOf返回的CompletableFuture。如果任意一个任务异常,allOf的CompletableFuture,执行get方法,会抛出异常 *
*
* @throws ExecutionException
* @throws InterruptedException
*/
public static void allOfExample() throws ExecutionException, InterruptedException {
CompletableFuture completableFuture1 = CompletableFuture.supplyAsync(() -> {
try {
Thread.sleep(1001);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("completableFuture1-当前线程名称:" + Thread.currentThread().getName());
return "当前线程1执行结束";
});
CompletableFuture completableFuture2 = CompletableFuture.supplyAsync(() -> {
try {
Thread.sleep(1001);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("completableFuture2-当前线程名称:" + Thread.currentThread().getName());
// throw new RuntimeException("咳咳!执行异常啦");
return "当前线程2执行结束";
});
CompletableFuture completableFuture = CompletableFuture.allOf(completableFuture1, completableFuture2).whenComplete((msg1, msg2) -> {
System.out.println("allOf----所有线程执行结束---" + msg1);
System.out.println("allOf----所有线程执行结束---" + msg2);
});
System.out.println("主线程-------acceptEitherExample-----正在执行2");
System.out.println(completableFuture.get());
}
执行结果
主线程-------acceptEitherExample-----正在执行2
completableFuture1-当前线程名称:ForkJoinPool.commonPool-worker-9
completableFuture2-当前线程名称:ForkJoinPool.commonPool-worker-2
allOf----所有线程执行结束---null
allOf----所有线程执行结束---null
null
AnyOf代码示例
public static void anyOfExample() throws ExecutionException, InterruptedException {
CompletableFuture completableFuture1 = CompletableFuture.supplyAsync(() -> {
try {
Thread.sleep(1001);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("completableFuture1-当前线程名称:" + Thread.currentThread().getName());
return "当前线程1执行结束";
});
CompletableFuture completableFuture2 = CompletableFuture.supplyAsync(() -> {
try {
Thread.sleep(1001);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("completableFuture2-当前线程名称:" + Thread.currentThread().getName());
return "当前线程2执行结束";
});
CompletableFuture
运行结果
主线程-------anyOfExample-----正在执行2
completableFuture1-当前线程名称:ForkJoinPool.commonPool-worker-9
completableFuture2-当前线程名称:ForkJoinPool.commonPool-worker-2
anyOf----所有线程执行结束---当前线程1执行结束
anyOf----所有线程执行结束---null
当前线程1执行结束
2.3.4thenCompose
thenCompose方法会在某个任务执行完成后,将该任务的执行结果,作为方法入参,去执行指定的方法。该方法会返回一个新的CompletableFuture实例
是对另一个CompletableFuture进行计算、操作,也就是说用来连接两个CompletableFuture,是生成一个新的CompletableFuture。
代码示例
public static void thenComposeExample() throws ExecutionException, InterruptedException {
CompletableFuture completableFuture1 = CompletableFuture.supplyAsync(() -> {
System.out.println("completableFuture1-当前线程名称:" + Thread.currentThread().getName());
return "当前线程1执行结束";
},executor).thenCompose(result -> CompletableFuture.supplyAsync(() -> {
System.out.println(result + "当前线程2执行结束-当前线程名称:" + Thread.currentThread().getName());
return result + "当前线程2执行结束";
},executor));
System.out.println(completableFuture1.get());
}
执行结果
completableFuture1-当前线程名称:completableFuture-executor-1
当前线程1执行结束当前线程2执行结束-当前线程名称:completableFuture-executor-2
当前线程1执行结束当前线程2执行结束