1、介绍
2、使用
2.1 异步执行
CompletableFuture提供了四种异步方法执行任务,为以下4种
public static <U> CompletableFuture<U> supplyAsync(Supplier<U> supplier){
return asyncSupplyStage(ASYNC_POOL, supplier);
}
public static <U> CompletableFuture<U> supplyAsync(Supplier<U> supplier,
Executor executor) {
return asyncSupplyStage(screenExecutor(executor), supplier);
}
public static CompletableFuture<Void> runAsync(Runnable runnable) {
return asyncRunStage(ASYNC_POOL, runnable);
}
public static CompletableFuture<Void> runAsync(Runnable runnable,
Executor executor) {
return asyncRunStage(screenExecutor(executor), runnable);
}
- 结合入参及方法,我们可用看出,以上四种方法其实可以分为2种 runAsync、supplyAsync。Executor executor 参数为指定的线程池,如果不指定则使用默认线程池。
- runAsync方法是返回值方法,supplyAsync为由返回值方法
2.2 并行方法
添加异步执行方法
private static String sleepSecond(int x) {
long sleep = 1000L * x;
try {
Thread.sleep(sleep);
}catch (Exception e) {
}
String print = "睡眠%d秒";
System.out.println(String.format(print, x));
return String.valueOf(x);
}
- allOf():当给定的所有CompletableFuture执行完成时,返回结果
- allOf() 方法返回值无法获取异步执行方法的值,可以直接根据执行supplyAsync返回结果get()获取值
- 以下为执行过程及结果
String print = "任务执行%d秒";
long start = System.currentTimeMillis();
CompletableFuture<String> future1 = CompletableFuture.supplyAsync(() -> sleepSecond(1));
CompletableFuture<String> future2 = CompletableFuture.supplyAsync(() -> sleepSecond(2));
CompletableFuture<String> future3 = CompletableFuture.supplyAsync(() -> sleepSecond(3));
CompletableFuture<Void> voidCompletableFuture = CompletableFuture.allOf(future1, future2, future3);
System.out.println(voidCompletableFuture.get());
System.out.println(future1.get());
System.out.println(future2.get());
System.out.println(future3.get());
System.out.println(String.format(print, ( System.currentTimeMillis() - start)/1000));
- anyOf():当任意CompletableFuture执行完成时,返回结果
- 使用anyOf()返回值对象进行get(),可以获取运行结果最快的方法的返回值
- 当使用supplyAsync返回结果get()获取值时,如果,则结果和allOf()一致
String print = "任务执行%d秒";
long start = System.currentTimeMillis();
CompletableFuture<String> future1 = CompletableFuture.supplyAsync(() -> sleepSecond(1));
CompletableFuture<String> future2 = CompletableFuture.supplyAsync(() -> sleepSecond(2));
CompletableFuture<String> future3 = CompletableFuture.supplyAsync(() -> sleepSecond(3));
CompletableFuture<Object> objectCompletableFuture = CompletableFuture.anyOf(future1, future2, future3);
System.out.println(objectCompletableFuture.get());
System.out.println(String.format(print, (System.currentTimeMillis() - start) / 1000));
String print = "任务执行%d秒";
long start = System.currentTimeMillis();
CompletableFuture<String> future1 = CompletableFuture.supplyAsync(() -> sleepSecond(1));
CompletableFuture<String> future2 = CompletableFuture.supplyAsync(() -> sleepSecond(2));
CompletableFuture<String> future3 = CompletableFuture.supplyAsync(() -> sleepSecond(3));
CompletableFuture<Object> objectCompletableFuture = CompletableFuture.anyOf(future1, future2, future3);
System.out.println(objectCompletableFuture.get());
System.out.println(future1.get());
System.out.println(future2.get());
System.out.println(future3.get());
System.out.println(String.format(print, (System.currentTimeMillis() - start) / 1000));
2.3 依赖关系
异步执行方法见2.2
- thenApply():将前面的任务执行的结果当作入参给thenApply()方法
- 注:thenApply()的入参类型和前面执行方法的返回值类型相同
- 以下为方法执行代码及结果
String print = "任务执行%d秒";
long start = System.currentTimeMillis();
CompletableFuture<String> future = CompletableFuture.supplyAsync(() -> sleepSecond(1))
.thenApply(e -> sleepSecond(Integer.parseInt(e) + 1));
System.out.println(future.get());
System.out.println(String.format(print, (System.currentTimeMillis() - start) / 1000));
- thenCompose():用来执行两个相关联的任务,返回结果为第二个任务的结果。一般用来执行第二个任务需要第一个任务返回结果处理业务
- 以下为方法执行代码及结果
// 此处为2.2异步演示代码的关联演示代码
private static CompletionStage<String> completionTest(String x) {
System.out.println("执行关联任务:" + x);
CompletableFuture<String> future =CompletableFuture.supplyAsync(() -> sleepSecond(Integer.parseInt(x) + 1));
return future;
}
// 具体的代码演示
String print = "任务执行%d秒";
long start = System.currentTimeMillis();
CompletableFuture<String> future = CompletableFuture.supplyAsync(() -> sleepSecond(1))
.thenCompose(CompletableFutureDemo::completionTest);
System.out.println(future.get());
System.out.println(String.format(print, (System.currentTimeMillis() - start) / 1000));
2.4 并且合集关系
异步执行方法见2.2
- thenCombine():将任务合并执行(多线程执行),并且可以将任务返回值进行一起处理
- 以下为方法执行代码及结果
String print = "任务执行%d秒";
long start = System.currentTimeMillis();
CompletableFuture<String> future = CompletableFuture.supplyAsync(() -> sleepSecond(1));
CompletableFuture<String> future1 = CompletableFuture.supplyAsync(() -> sleepSecond(2));
CompletableFuture<String> combine = future.thenCombine(future1, new BiFunction<String, String, String>() {
@Override
public String apply(String s, String s2) {
System.out.println(s + "," + s2);
return s + s2;
}
});
System.out.println(combine.get());
System.out.println(String.format(print, (System.currentTimeMillis() - start) / 1000));
- thenAcceptBoth():两个任务执行完成后,将两个任务分返回值进行处理
- 以下为方法执行代码及结果
String print = "任务执行%d秒";
long start = System.currentTimeMillis();
CompletableFuture<String> future = CompletableFuture.supplyAsync(() -> sleepSecond(1));
CompletableFuture<String> future1 = CompletableFuture.supplyAsync(() -> sleepSecond(2));
future.get();
future1.get();
future.thenAcceptBoth(future1, new BiConsumer<String, String>() {
@Override
public void accept(String s, String s2) {
System.out.println(s + ',' + s2);
}
});
System.out.println(String.format(print, (System.currentTimeMillis() - start) / 1000));
- runAfterBoth():正在两个方法都执行完成后,再执行下一步Runable()方法
- 以下为方法执行代码及结果
String print = "任务执行%d秒";
long start = System.currentTimeMillis();
CompletableFuture<String> future = CompletableFuture.supplyAsync(() -> sleepSecond(1));
CompletableFuture<String> future1 = CompletableFuture.supplyAsync(() -> sleepSecond(2));
future.get();
future1.get();
future.runAfterBoth(future1, new Runnable() {
@Override
public void run() {
System.out.println("执行 runAfterBoth()方法");
}
});
System.out.println(String.format(print, (System.currentTimeMillis() - start) / 1000));
2.5 或者聚合执行方法
异步执行方法见2.2
- applyToEither():两个执行的方法使用执行快的方法返回值,该方法有返回值
- 以下为方法执行代码及结果
String print = "任务执行%d秒";
long start = System.currentTimeMillis();
CompletableFuture<String> future = CompletableFuture.supplyAsync(() -> sleepSecond(1))
.applyToEither(CompletableFuture.supplyAsync(() -> sleepSecond(2)), new Function<String, String>() {
@Override
public String apply(String s) {
System.out.println("输出返回最快的结果值" + s);
return s;
}
});
future.get();
System.out.println(String.format(print, (System.currentTimeMillis() - start) / 1000));
- acceptEither():两个任务执行后,去执行最快的结果
- 以下为方法执行代码及结果
String print = "任务执行%d秒";
long start = System.currentTimeMillis();
CompletableFuture<Void> either = CompletableFuture.supplyAsync(() -> sleepSecond(1))
.acceptEither(CompletableFuture.supplyAsync(() -> sleepSecond(2)), new Consumer<String>() {
@Override
public void accept(String s) {
System.out.println("输出执行快的结果" + s);
}
});
either.get();
System.out.println(String.format(print, (System.currentTimeMillis() - start) / 1000));
- runAfterEither():任意一个任务执行完成,执行Runnable()方法
- 以下为方法执行代码及结果
String print = "任务执行%d秒";
long start = System.currentTimeMillis();
CompletableFuture<Void> either = CompletableFuture.supplyAsync(() -> sleepSecond(1))
.runAfterEither(CompletableFuture.supplyAsync(() -> sleepSecond(2)), new Runnable() {
@Override
public void run() {
System.out.println("任意任务完成后执行方法");
}
});
either.get();
System.out.println(String.format(print, (System.currentTimeMillis() - start) / 1000));