下面是自己总结的一部分的api的使用,当然下面有些方法后面加上Async就会变为异步的
/**
* 变换:参数为Function接口
* thenApply:将上一个结果当做这次thenApply的参数传入,加以处理后,返回一个值
* 可以传入T返回T也可以传入T返回U
*/
public void thenApply() {
CompletableFuture<String> future = CompletableFuture.supplyAsync(()-> 1).thenApply(i -> String.valueOf(i));
String i = future.join();
System.out.println(i); //1
}
/**
* 消费
* 参数为Consumer接口
* thenAccept:将上一个的结果当做这次的参数传入,但是无返回值
*/
public void thenAccept() {
CompletableFuture<Void> future = CompletableFuture.supplyAsync(() -> 1).thenAccept((integer -> System.out.println(integer)));
future.join(); //1
}
public void thenCompose() {
CompletableFuture<Integer> future = CompletableFuture.supplyAsync(() -> 1) //提供第一个CompletableFuture结果值
.thenCompose((i) -> //将上一个结果值传入下一个CompletableFuture
CompletableFuture.supplyAsync(() -> i + 2)); //对传入的结果值进行处理
Integer join = future.join();
System.out.println(join);
}
/**
* 结合两个结果得到一个最终值
* 逻辑处理需要的是BiFunction接口
* 需要两个CompletableFuture结果,并且需要有处理两个结果的逻辑
* 两个CompletableFuture返回的结果不需要一致
*/
public void thenCombine() {
CompletableFuture<String> future = CompletableFuture.supplyAsync(() -> "Hello ") //第一个CompletableFuture返回结果
.thenCombine(CompletableFuture.supplyAsync(() -> 1), //第二个CompletableFuture返回结果
(future1, future2) -> future1 + future2); //处理两个结果的逻辑
String join = future.join();
System.out.println(join); //Hello World
}
/**
* 跟上面的差不多,只不过这里处理逻辑需要的是一个BiConsumer接口,无返回值而已
*/
public void thenAcceptBoth() {
CompletableFuture<Void> both = CompletableFuture.supplyAsync(() -> "Hello ") //第一个CompletableFuture返回结果
.thenAcceptBoth(CompletableFuture.supplyAsync(() -> "World"), //第二个CompletableFuture返回结果
(future1, future2) -> System.out.println(future1 + future2));//处理两个结果的逻辑
both.join(); //Hello World
}
/**
* 两个CompletableFuture一起执行,哪个先执行完就用哪个CompletableFuture的结果
* 处理逻辑需要的参数是一个Function接口
* 下面整体代码的逻辑是返回1的睡眠一秒,返回2的睡眠0.3秒,所以返回2的肯定比1要快,所以结果为2,然后应用到处理逻辑上
* 最终结果就是为 2 done
* 两个CompletableFuture返回的参数需要一致
* 这适用于两种渠道完成同一个事情,就可以调用这个方法,找一个最快的结果进行处理,最终有返回值。
*/
public void applyToEither() {
CompletableFuture<String> apply = CompletableFuture.supplyAsync(() -> {
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
return "1";
}).applyToEither(
CompletableFuture.supplyAsync(() -> {
try {
Thread.sleep(300);
} catch (InterruptedException e) {
e.printStackTrace();
}
return "2";
}),
(future) -> future + " done" //对于首先完成的CompletableFuture任务之后执行的逻辑
);
String join = apply.join();
System.out.println(join);//2 done
}
/**
* 与上面使用方法一致,只是多加了一个选项
* 结果为3 three
*/
public void applyToEithers() {
CompletableFuture<String> apply = CompletableFuture.supplyAsync(() -> {
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
return "1";
}).applyToEither(
CompletableFuture.supplyAsync(() -> {
try {
Thread.sleep(800);
} catch (InterruptedException e) {
e.printStackTrace();
}
return "2";
}),(future) -> future + " done" //对于首先完成的CompletableFuture任务之后执行的逻辑
).applyToEither(
CompletableFuture.supplyAsync(() -> {
try {
Thread.sleep(300);
} catch (InterruptedException e) {
e.printStackTrace();
}
return "3";
}),(future -> future + " three")
);
String join = apply.join();
System.out.println(join);//2 done
}
/**
* 对于出错的处理过程进行补偿,即如果future出错,会运行exceptionally里的Function函数
* 当然没有错就不会运行后面指定的函数
*/
@Test
public void exceptionally() {
CompletableFuture<String> exceptionally = CompletableFuture.supplyAsync(() -> {
int i = 1 / 0 ;
return "1";
}).exceptionally(ex -> {
ex.printStackTrace();
return "error";
});
String join = exceptionally.join();
System.out.println(join);
}
/**
* 输出
* error
* java.util.concurrent.CompletionException: java.lang.ArithmeticException: / by zero
* at java.util.concurrent.CompletableFuture.encodeThrowable(CompletableFuture.java:273)
* at java.util.concurrent.CompletableFuture.completeThrowable(CompletableFuture.java:280)
* at java.util.concurrent.CompletableFuture$AsyncSupply.run(CompletableFuture.java:1592)
* at java.util.concurrent.CompletableFuture$AsyncSupply.exec(CompletableFuture.java:1582)
* at java.util.concurrent.ForkJoinTask.doExec(ForkJoinTask.java:289)
* at java.util.concurrent.ForkJoinPool$WorkQueue.runTask(ForkJoinPool.java:1056)
* at java.util.concurrent.ForkJoinPool.runWorker(ForkJoinPool.java:1692)
* at java.util.concurrent.ForkJoinWorkerThread.run(ForkJoinWorkerThread.java:157)
* Caused by: java.lang.ArithmeticException: / by zero
* at com.qidai.demotest.MyTestx.lambda$exceptionally$18(MyTestx.java:125)
* at java.util.concurrent.CompletableFuture$AsyncSupply.run(CompletableFuture.java:1590)
* ... 5 more
*/
/**
* 与上面的thenAccept相比较,这个方法并不需要输入参数,相同点是都是无返回值
*/
public void thenRun() {
CompletableFuture<Void> runnable = CompletableFuture.supplyAsync(() -> "1").thenRun(() -> System.out.println("runnable"));
runnable.join();
}