package com.example.thread.juc.completablefuture;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ExecutionException;
import static java.lang.System.currentTimeMillis;
import static java.lang.System.out;
/**
* completableFuture Java中的并发线程工具类
*
* 适用于
* 存在线程之间相互依赖,等待线程结果,线程之间关联,异步回调
* 线程之间And关系,或者 or 关系,
*
*/
public class ExampleCompletableFuture {
public static void main(String[] args) throws ExecutionException, InterruptedException {
//completableFutureSupplyAsync();
//completableFutureRunAsync();
//completableFutureSupplyAsyncAndThenApply();
//completableFutureSupplyAsyncAndThenApplyAsync();
//completableFutureSupplyAsyncAndExceptionally();
//completableFutureSupplyAsyncAndWhenComplete();
//completableFutureCombine();
//completableFutureEither();
completableFutureCompPost();
}
//================================异步回调===DEMO===begin================================================
/**
* CompletableFuture.supplyAsync 与线程池中的 Executor.submit(Future ) 异步带有返回值的逻辑一致
* supplyAsync(任务);//带有返回值的异步执行,通过 get()阻塞调用线程
*
*/
public static void completableFutureSupplyAsync() throws ExecutionException, InterruptedException {
CompletableFuture<Double> cf = CompletableFuture.supplyAsync(() -> {
long l = currentTimeMillis();
out.println("supplyAsync" + l);
try {
Thread.sleep(3000);
} catch (InterruptedException e) {
e.printStackTrace();
}
out.println("cha:" + (currentTimeMillis() - l));
return 1.2;
});
out.println("lol");
Double aDouble = cf.get();
out.println("CompletableFuture" + aDouble);
}
/**
* CompletableFuture.runAsync 和线程池中 submit(Runnable) 逻辑一致,只会执行任务,不带返回值
* get()方法还是会阻塞调用线程
* @throws ExecutionException
* @throws InterruptedException
*/
public static void completableFutureRunAsync() throws ExecutionException, InterruptedException {
CompletableFuture<Void> voidCompletableFuture = CompletableFuture.runAsync(() -> {
out.println("begin");
try {
Thread.sleep(3000);
} catch (InterruptedException e) {
e.printStackTrace();
}
out.println("end");
});
Void aVoid = voidCompletableFuture.get();
out.println("void");
}
/**
* completableFuture.supplyAsync后调用thenApply实现细节是:
* 异步回调,thenApply中的任务会等待supply中的任务返回结果后才会执行且thenApply也需要返回结果
* thenApply执行的线程是supplyAsync中的线程继续执行的,没有重新创建线程执行thenApply中的任务
* 同样调用 get()方法会阻塞调用线程,返回结果时唤醒调用get线程,
* @throws ExecutionException
* @throws InterruptedException
*/
public static void completableFutureSupplyAsyncAndThenApply() throws ExecutionException, InterruptedException {
CompletableFuture<String> cf = CompletableFuture.supplyAsync(() -> {
out.println("["+Thread.currentThread().getName() + " ]first SupplyAsync");
try {
//为什么使用 Sleep,模拟业务逻辑执行时间
Thread.sleep(2000);
} catch (InterruptedException e) {
e.printStackTrace();
}
out.println("first SupplyAsync Sleep End");
return "first SupplyAsync";
});
CompletableFuture<String> cf2 = cf.thenApply(s -> {
out.println("["+Thread.currentThread().getName() + "]thenApply");
try {
//为什么使用 Sleep,模拟业务逻辑执行时间
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
out.println("thenApply Sleep end");
return s + " thenApply";
});
out.println("main begin");
String s = cf.get();//阻塞 等待cf执行完成
out.println("cf result:"+s);
String s1 = cf2.get();
out.println("c2 result:" + s1);
out.println("main end");
}
/**
* completableFuture.supplyAsync后调用thenApply实现细节是:
* 异步回调,thenApplyAsync中的任务会等待supply中的任务返回结果后才会执行且thenApply也需要返回结果
* thenApplyAsync执行的线程是有可能重新启动线程执行里面的任务,也有可能是supply中的线程继续执行
*
* 同样调用 get()方法会阻塞调用线程,返回结果时唤醒调用get线程,
* @throws ExecutionException
* @throws InterruptedException
*/
public static void completableFutureSupplyAsyncAndThenApplyAsync() throws ExecutionException, InterruptedException {
CompletableFuture<String> cf = CompletableFuture.supplyAsync(() -> {
out.println("["+Thread.currentThread().getName() + " ]first SupplyAsync");
try {
//为什么使用 Sleep,模拟业务逻辑执行时间
Thread.sleep(2000);
} catch (InterruptedException e) {
e.printStackTrace();
}
out.println("first SupplyAsync Sleep End");
return "first SupplyAsync";
});
CompletableFuture<String> cf2 = cf.thenApplyAsync(s -> {
out.println("["+Thread.currentThread().getName() + "]thenApply");
try {
//为什么使用 Sleep,模拟业务逻辑执行时间
Thread.sleep(2000);
} catch (InterruptedException e) {
e.printStackTrace();
}
out.println("thenApply Sleep end");
return s + " thenApply";
});
out.println("main begin");
String s = cf.get();//阻塞 等待cf执行完成
out.println("cf result:"+s);
String s1 = cf2.get();
out.println("c2 result:" + s1);
out.println("main end");
}
/**
* completableFuture.supplyAsync后调用thenApply实现细节是:
* 异步回调,thenApplyAsync中的任务会等待supply中的任务返回结果后才会执行且thenAccept接收supply值,不需要返回结果
* thenApplyAsync执行的线程是有可能重新启动线程执行里面的任务,也有可能是supply中的线程继续执行
*
* 同样调用 get()方法会阻塞调用线程,返回结果时唤醒调用get线程,
* @throws ExecutionException
* @throws InterruptedException
*/
public static void completableFutureSupplyAsyncAndThenAccept() throws ExecutionException, InterruptedException {
CompletableFuture<String> cf = CompletableFuture.supplyAsync(() -> {
out.println("["+Thread.currentThread().getName() + " ]first SupplyAsync");
try {
//为什么使用 Sleep,模拟业务逻辑执行时间
Thread.sleep(2000);
} catch (InterruptedException e) {
e.printStackTrace();
}
out.println("first SupplyAsync Sleep End");
return "first SupplyAsync";
});
CompletableFuture<Void> cf2 = cf.thenAccept(s -> {
out.println("["+Thread.currentThread().getName() + "]thenApply");
try {
//为什么使用 Sleep,模拟业务逻辑执行时间
Thread.sleep(2000);
} catch (InterruptedException e) {
e.printStackTrace();
}
out.println("thenApply Sleep end");
});
out.println("main begin");
String s = cf.get();//阻塞 等待cf执行完成
out.println("cf result:"+s);
Void aVoid = cf2.get();
out.println("main end" + aVoid);
}
/**
* completableFuture.supplyAsync后调用thenRunAsync实现细节是:
* 异步回调,thenRunAsync中的任务会等待supply中的任务返回结果后才会执行且thenRun "不" 接收supply值,不需要返回结果
* thenRunAsync执行的线程是有可能重新启动线程执行里面的任务,也有可能是supply中的线程继续执行
*
* 同样调用 get()方法会阻塞调用线程,返回结果时唤醒调用get线程,
* @throws ExecutionException
* @throws InterruptedException
*/
public static void completableFutureSupplyAsyncAndThenRun() throws ExecutionException, InterruptedException {
CompletableFuture<String> cf = CompletableFuture.supplyAsync(() -> {
out.println("["+Thread.currentThread().getName() + " ]first SupplyAsync");
try {
//为什么使用 Sleep,模拟业务逻辑执行时间
Thread.sleep(2000);
} catch (InterruptedException e) {
e.printStackTrace();
}
out.println("first SupplyAsync Sleep End");
return "first SupplyAsync";
});
CompletableFuture<Void> cf2 = cf.thenRun(() -> {
out.println("["+Thread.currentThread().getName() + "]thenApply");
try {
//为什么使用 Sleep,模拟业务逻辑执行时间
Thread.sleep(2000);
} catch (InterruptedException e) {
e.printStackTrace();
}
out.println("thenApply Sleep end");
});
out.println("main begin");
String s = cf.get();//阻塞 等待cf执行完成
out.println("cf result:"+s);
Void aVoid = cf2.get();
out.println("main end" + aVoid);
}
/**
* completableFuture.supplyAsync后调用exceptionally实现细节是:
* 异步回调异常处理且有返回值,
* supply中执行任务出现异常,直接调用 exceptionally 异常处理,
* 而supply后续的异步回调任务则不会调用后续的异步任务
*
* 同样调用 get()方法会阻塞调用线程,返回结果时唤醒调用get线程,
* @throws ExecutionException
* @throws InterruptedException
*/
public static void completableFutureSupplyAsyncAndExceptionally() throws ExecutionException, InterruptedException {
CompletableFuture<String> cf = CompletableFuture.supplyAsync(() -> {
out.println("["+Thread.currentThread().getName() + " ]first SupplyAsync");
try {
//为什么使用 Sleep,模拟业务逻辑执行时间
Thread.sleep(2000);
} catch (InterruptedException e) {
e.printStackTrace();
}
if(true){
throw new RuntimeException("throw Exceptionally supplyAsync");
}else{
out.println("first SupplyAsync Sleep End");
return "first SupplyAsync";
}
});
//exceptionally 会捕获 cf抛出的异常,然后进行处理 且可以返回自定义的结果
CompletableFuture<String> cf2 = cf.exceptionally(ex -> {
out.println(" enter exceptionally");
try {
//为什么使用 Sleep,模拟业务逻辑执行时间
Thread.sleep(2000);
} catch (InterruptedException e) {
e.printStackTrace();
}
ex.printStackTrace();
out.println("out exceptionally");
return "exceptionally";
});
CompletableFuture<String> cf3 = cf.thenApply(s -> {
out.println("send thenApply");
try {
//为什么使用 Sleep,模拟业务逻辑执行时间
Thread.sleep(2000);
} catch (InterruptedException e) {
e.printStackTrace();
}
out.println("send thenApply Sleep End");
return s + "thenApply";
});
out.println("main begin");
String s = cf.get();
out.println("cf result:" + s);
String s1 = cf2.get();
out.println("cf2 result:" + s1);
String s2 = cf3.get();
out.println("cf3 result:" + s2);
out.println("main End");
}
/**
* completableFuture.supplyAsync后调用whenComplete实现细节是:
* 异步回调异常处理且有返回值,
* supply中执行任务出现异常,直接调用 whenComplete 有两个参数:a = supply的返回值,b = supply中抛出的异常
* whenComplete 默认返回 supply中的返回值,是同一个
*
* completableFuture.supplyAsync后调用handleAsync实现细节是:
* 异步回调异常处理且有返回值,
* supply中执行任务出现异常,直接调用 whenComplete 有两个参数:a = supply的返回值,b = supply中抛出的异常
* whenComplete 默认返回 supply中的返回值,是不是同一个,有handler中自定义
*
* @throws ExecutionException
* @throws InterruptedException
*/
public static void completableFutureSupplyAsyncAndWhenComplete() throws ExecutionException, InterruptedException {
CompletableFuture<String> cf = CompletableFuture.supplyAsync(() -> {
out.println("first SupplyAsyncWhen");
try {
//为什么使用 Sleep,模拟业务逻辑执行时间
Thread.sleep(2000);
} catch (InterruptedException e) {
e.printStackTrace();
}
if (true) {
throw new RuntimeException("when Exception");
} else {
out.println("first SupplyAsyncWhen Sleep End");
return "first SupplyAsyncWhen";
}
});
CompletableFuture<String> cf2 = cf.whenComplete((a, b) -> {
out.println("whenComplete enter");
try {
//为什么使用 Sleep,模拟业务逻辑执行时间
Thread.sleep(2000);
} catch (InterruptedException e) {
e.printStackTrace();
}
if (b != null) {
b.printStackTrace();
}else{
out.println("whenComplete a:"+a);
}
});
/*CompletableFuture<String> stringCompletableFuture = cf.handleAsync((a, b) -> {
System.out.println("handler enter");
try {
//为什么使用 Sleep,模拟业务逻辑执行时间
Thread.sleep(2000);
} catch (InterruptedException e) {
e.printStackTrace();
}
if (b != null) {
b.printStackTrace();
}else{
System.out.println("whenComplete a:"+a);
}
return "handler";
});*/
out.println("main begin");
String s = cf2.get();
out.println("cf2 :" + s);
}
//================================异步回调===DEMO===End================================================
//================================组合处理===DEMO===begin================================================
/**
* =================thenCombine=====thenAcceptBoth===runAfterBoth==============
*
* thenCombine,是有两个带有返回值的 completableFuture组合,只有两个都执行完成,才会执行thenCombine中的任务
* 两个supply是并行的,但是thenCombine 会等待两个执行完成才会执行,然后取得两个任务的返回值
*
* thenCombine 需要自定义返回值,可获取到组合的返回值
* thenAcceptBoth 无返回值,可获取到组合的返回值
* runAfterBoth 无返回值,获取不到组合的返回值
* 同样调用 get()方法会阻塞调用线程,返回结果时唤醒调用get线程,
* @throws ExecutionException
* @throws InterruptedException
*/
public static void completableFutureCombine() throws ExecutionException, InterruptedException {
CompletableFuture<Double> cf = CompletableFuture.supplyAsync(() -> {
try {
Thread.sleep(2000);
} catch (InterruptedException e) {
e.printStackTrace();
}
return 13.0;
});
CompletableFuture<Double> cf2 = CompletableFuture.supplyAsync(() -> {
try {
Thread.sleep(2000);
} catch (InterruptedException e) {
e.printStackTrace();
}
return 1.0;
});
//注意 组合明细必须使用 引用类型
CompletableFuture<String> cf3=cf.thenCombine(cf2,(a,b)->{
out.println("combine begin");
out.println("job3 param a->"+a+",b->"+b);
try {
Thread.sleep(2000);
} catch (InterruptedException e) {
}
out.println(Thread.currentThread()+" exit job3,time->"+ currentTimeMillis());
return a + " " +b;
});
CompletableFuture<Void> voidCompletableFuture = cf.thenAcceptBoth(cf2, (a, b) -> {
//可获取 a ,b的执行结果
//无返回值
});
CompletableFuture<Void> voidCompletableFuture1 = cf.runAfterBoth(cf2, () -> {
//获取不到 a , b 的结果
//无返回值
});
out.println("main begin");
String s = cf3.get();
out.println("cf3 result:" + s);
}
/**
* =================applyToEither=====AcceptToEither===runAfterEither==============
*
* applyToEither,是有两个带有返回值的 completableFuture组合,只有两个都执行完成,才会执行thenCombine中的任务
* 两个supply是并行的,但是thenCombine 会等待两个执行完成才会执行,然后取得最先完成的任务的返回值(只有一个参数)
*
* applyToEither 需要自定义返回值,可获取到组合的返回值(1个)
* AcceptToEither 无返回值,可获取到组合的返回值
* runAfterEither 无返回值,获取不到组合的返回值
* 同样调用 get()方法会阻塞调用线程,返回结果时唤醒调用get线程,
* @throws ExecutionException
* @throws InterruptedException
*/
public static void completableFutureEither() throws ExecutionException, InterruptedException {
CompletableFuture<Double> cf = CompletableFuture.supplyAsync(() -> {
try {
Thread.sleep(3000);
} catch (InterruptedException e) {
e.printStackTrace();
}
return 13.0;
});
CompletableFuture<Double> cf2 = CompletableFuture.supplyAsync(() -> {
try {
Thread.sleep(2000);
} catch (InterruptedException e) {
e.printStackTrace();
}
return 1.0;
});
CompletableFuture<Double> cf3 = cf.applyToEither(cf2, (result) -> {
out.println("Either begin");
out.println("job3 param result->"+result);
try {
Thread.sleep(2000);
} catch (InterruptedException e) {
}
out.println(Thread.currentThread()+" exit job3,time->"+ currentTimeMillis());
return result;
});
cf.acceptEither(cf2,(result)->{
//有参数
//无返回值
});
cf.runAfterEither(cf2,()->{
//无参数
//无返回值
});
out.println("main begin");
Double s = cf3.get();
out.println("cf3 result:" + s);
}
/**
* thenCompose 为等待cf执行完成后将参数传入到 thenCompose中执行,
* thenCompose 会返回 新的 CompletableFuture实例,
* @throws ExecutionException
* @throws InterruptedException
*/
public static void completableFutureCompPost() throws ExecutionException, InterruptedException {
CompletableFuture<Double> cf = CompletableFuture.supplyAsync(() -> {
try {
Thread.sleep(3000);
} catch (InterruptedException e) {
e.printStackTrace();
}
return 13.0;
});
CompletableFuture<String> cf2 = cf.thenCompose((e) -> {
out.println("e:" + e );
return CompletableFuture.supplyAsync(() -> {
return "dfa";
});
});
String s = cf2.get();
out.println(s);
}
/**
* //allof等待所有任务执行完成才执行cf4,如果有一个任务异常终止,则cf4.get时会抛出异常,都是正常执行,cf4.get返回null
* //anyOf是只有一个任务执行完成,无论是正常执行或者执行异常,都会执行cf4,cf4.get的结果就是已执行完成的任务的执行结果
*
*/
public static void completableFutureAnyall(){
CompletableFuture<String> cf = CompletableFuture.supplyAsync(() -> {
return "cf";
});
CompletableFuture<String> cf1 = CompletableFuture.supplyAsync(() -> {
return "cf1";
});
CompletableFuture<String> cf2 = CompletableFuture.supplyAsync(() -> {
return "cf2";
});
CompletableFuture<Void> cf4 = CompletableFuture.allOf(cf, cf1, cf2).whenComplete((a, e) -> {
});
CompletableFuture<String> cf5 = CompletableFuture.anyOf(cf, cf1, cf2).thenCompose((e) -> {
return CompletableFuture.supplyAsync(() -> "sdfsd");
});
}
}
ComplatebleFuture组合式异步编程
最新推荐文章于 2024-11-09 12:43:52 发布