一句话:Future接口可以为主线程开一个分支任务,专门为主线程处理耗时和费力的复杂业务。
有个目的:异步多线程任务执行且有返回结果,三个特点:多线程/有返回值/异步任务(班长作为老师去买水作为新启动的异步多线程任务且买到水有结果返回)
从我们的需求来分析,我们的异步多线程任务执行且返回有结果,可以看出来三个特点
ctrl
+alt
+u
) IDEA能帮助我们生成类的继承关系图使用
public class CompletableFutureDemo {
public static void main(String[] args) throws ExecutionException, InterruptedException {
FutureTask<String> stringFutureTask = new FutureTask<String>(new MyThread2());
Thread thread = new Thread(stringFutureTask);
thread.start();
System.out.println(stringFutureTask.get());
}
}
class MyThread2 implements Callable<String>{
@Override
public String call() throws Exception {
System.out.println("-----come in call() ----异步执行");
return "hello Callable 返回值";
}
}
-----come in call() ----异步执行
hello Callable 返回值
方案一,3个任务1个main线程处理,大概1130ms
public static void main(String[] args) throws InterruptedException {
//3个任务,目前只有一个线程main来处理
long startTime = System.currentTimeMillis();
//暂停毫秒
TimeUnit.MILLISECONDS.sleep(500);
TimeUnit.MILLISECONDS.sleep(300);
TimeUnit.MILLISECONDS.sleep(300);
long endTime= System.currentTimeMillis();
System.out.println((endTime-startTime)+"毫秒");
System.out.println(Thread.currentThread().getName()+"\t--------end");
}
}
方案二,3个任务3个线程,利用线程池(假如每次new一个Thread,太浪费资源,会有GC这些工作),大概400毫秒。
public class FutureDemo1 {
public static void main(String[] args) throws InterruptedException {
//3个任务,开启多个异步任务线程进行处理
ExecutorService executorService = Executors.newFixedThreadPool(3);
long startTime = System.currentTimeMillis();
FutureTask<String> futureTask1 = new FutureTask<>(() -> {
TimeUnit.MILLISECONDS.sleep(500);
return "task1 over";
});
executorService.submit(futureTask1);
FutureTask<String> futureTask2 = new FutureTask<>(() -> {
TimeUnit.MILLISECONDS.sleep(300);
return "task2 over";
});
executorService.submit(futureTask2);
TimeUnit.MILLISECONDS.sleep(300);
long endTime = System.currentTimeMillis();
System.out.println((endTime-startTime)+"毫秒");
System.out.println(Thread.currentThread().getName()+"\t--------end");
}
}
一旦调用get()方法,不管是否计算完成,都会导致阻塞(所以一般get方法放到最后)
public class FutureDemo2 {
public static void main(String[] args) throws ExecutionException, InterruptedException {
FutureTask<String> futureTask1 = new FutureTask<String>(() -> {
System.out.println(Thread.currentThread().getName() + "\t ------副线程come in");
TimeUnit.SECONDS.sleep(3);
return "task over";
});
Thread thread = new Thread(futureTask1, "t1");
thread.start();
//-----------------------------------------------------------注意顺序
System.out.println(Thread.currentThread().getName()+"\t-------主线程忙其他任务了");
System.out.println(futureTask1.get());
//----------------------------------------------------------注意顺序
}
}
//t1 ------副线程come in
//main -------主线程忙其他任务了
//task over
public class FutureDemo2 {
public static void main(String[] args) throws ExecutionException, InterruptedException {
FutureTask<String> futureTask1 = new FutureTask<String>(() -> {
System.out.println(Thread.currentThread().getName() + "\t ------副线程come in");
TimeUnit.SECONDS.sleep(3);
return "task over";
});
Thread thread = new Thread(futureTask1, "t1");
thread.start();
//-----------------------------------------------------------注意顺序
System.out.println(futureTask1.get());
System.out.println(Thread.currentThread().getName()+"\t-------主线程忙其他任务了");
//----------------------------------------------------------注意顺序
}
}
//t1 ------副线程come in
//task over
//-------------------5秒后才出现下面的结果-------------说明一旦调用get()方法直接去找副线程了,阻塞了主线程
//main -------主线程忙其他任务了
利用if(futureTask.isDone())的方式使得他在结束之后才get(),但是也会消耗cpu
public class FutureDemo3 {
public static void main(String[] args) throws ExecutionException, InterruptedException {
FutureTask<String> futureTask = new FutureTask<String>(()->{
System.out.println(Thread.currentThread().getName()+"\t ------副线程come in");
TimeUnit.SECONDS.sleep(5);//暂停几秒
return "task over";
});
Thread t1 = new Thread(futureTask,"t1");
t1.start();
System.out.println(Thread.currentThread().getName()+"\t-------主线程忙其他任务了");
//1------- System.out.println(futureTask.get(3,TimeUnit.SECONDS));//只愿意等3秒,过了3秒直接抛出异常
//2-------更健壮的方式-------轮询方法---等副线程拿到才去get()
//但是也会消耗cpu资源
while(true){
if(futureTask.isDone()){
System.out.println(futureTask.get());
break;
}else{
//暂停毫秒
try {
TimeUnit.MILLISECONDS.sleep(500);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("正在处理中------------正在处理中");
}
}
}
}
//main -------主线程忙其他任务了
//t1 ------副线程come in
//正在处理中------------正在处理中
//正在处理中------------正在处理中
//正在处理中------------正在处理中
//正在处理中------------正在处理中
//正在处理中------------正在处理中
//正在处理中------------正在处理中
//正在处理中------------正在处理中
//正在处理中------------正在处理中
//正在处理中------------正在处理中
//正在处理中------------正在处理中
//task over
对于简单的业务场景使用Future完全OK
回调通知
创建异步任务
Future+线程池配合
多个任务前后依赖可以组合处理
想将多个异步任务的计算结果组合起来,后一个异步任务的计算结果需要前一个异步任务的值,将两个或多个异步计算合成一个异步计算,这几个异步计算相互独立,同时后面这个又依赖前一个处理的结果
比如买鱼-加料-烹饪
对计算速度选最快完成的(并返回结果)
public class CompletableFuture<T> implements Future<T>, CompletionStage<T>
在Java 8中, CompletableFuture提供了非常强大的Future的扩展功能, 可以帮助我们简化异步编程的复杂性, 并且提供了函数式编程的能力, 可以通过回调的方式处理计算结果,也提供了转换和组合CompletableFuture的方法。
它可能代表一个明确完成的Future, 也有可能代表一个完成阶段(Completion Stage) , 它支持在计算完成以后触发一些函数或执行某些动作。
它实现了Future和CompletionStage接口
利用核心的四个静态方法创建一个异步操作 | 不建议用new
关键就是 |有没有返回值|是否用了线程池|
参数说明:
没有指定Executor的方法,直接使用默认的ForkJoinPool.commPool()作为它的线程池执行异步代码。
如果指定线程池,则使用我们定义的或者特别指定的线程池执行异步代码。
public class CompletableFutureDemo1 {
public static void main(String[] args) throws ExecutionException, InterruptedException {
CompletableFuture<Void> voidCompletableFuture = CompletableFuture.runAsync(() -> {
System.out.println(Thread.currentThread().getName());
try {
TimeUnit.SECONDS.sleep(1);
} catch (InterruptedException e) {
e.printStackTrace();
}
});
System.out.println(voidCompletableFuture.get());
}
}
//ForkJoinPool.commonPool-worker-9
//null
runAsync+线程池
public class CompletableFutureDemo1 {
public static void main(String[] args) throws ExecutionException, InterruptedException {
//自定义
ExecutorService executorService = Executors.newFixedThreadPool(3);
CompletableFuture<Void> voidCompletableFuture = CompletableFuture.runAsync(() -> {
System.out.println(Thread.currentThread().getName());
try {
TimeUnit.SECONDS.sleep(1);
} catch (InterruptedException e) {
e.printStackTrace();
}
},executorService);
System.out.println(voidCompletableFuture.get());
}
}
//pool-1-thread-1
//null
public class CompletableFutureDemo1 {
public static void main(String[] args) throws ExecutionException, InterruptedException {
CompletableFuture<String> stringCompletableFuture = CompletableFuture.supplyAsync(() -> {
System.out.println(Thread.currentThread().getName());
try {
TimeUnit.SECONDS.sleep(1);
} catch (InterruptedException e) {
e.printStackTrace();
}
return "helllo supplyasync";
});
System.out.println(stringCompletableFuture.get());
}
}
//ForkJoinPool.commonPool-worker-9
//helllo supplyasync
supplyAsync+线程池
public class CompletableFutureDemo1 {
public static void main(String[] args) throws ExecutionException, InterruptedException {
ExecutorService executorService = Executors.newFixedThreadPool(3);
CompletableFuture stringCompletableFuture = CompletableFuture.supplyAsync(() -> {
System.out.println(Thread.currentThread().getName());
try {
TimeUnit.SECONDS.sleep(1);
} catch (InterruptedException e) {
e.printStackTrace();
}
return "helllo supplyasync";
},executorService);
System.out.println(stringCompletableFuture.get());
}
}
//pool-1-thread-1
//helllo supplyasync
CompletableFuture
可以完成Future
的功能public class CompletableFutureDemo3 {
public static void main(String[] args) throws ExecutionException, InterruptedException {
CompletableFuture<Integer> integerCompletableFuture = CompletableFuture.supplyAsync(() -> {
System.out.println(Thread.currentThread().getName() + "----副线程come in");
int result = ThreadLocalRandom.current().nextInt(10);
try {
TimeUnit.SECONDS.sleep(1);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("1秒钟后出结果"+result);
return result;
});
System.out.println(Thread.currentThread().getName()+"线程先去忙其他任务");
System.out.println(integerCompletableFuture.get());
}
}
//main线程先去忙其他任务
//ForkJoinPool.commonPool-worker-9----副线程come in
//1秒钟后出结果5
//5
CompletableFuture
通过whenComplete
来减少阻塞和轮询(自动回调)public class CompletableFutureDemo3 {
public static void main(String[] args) throws ExecutionException, InterruptedException {
CompletableFuture<Integer> exceptionally = CompletableFuture.supplyAsync(() -> {
System.out.println(Thread.currentThread().getName() + "----副线程come in");
int result = ThreadLocalRandom.current().nextInt(10);
try {
TimeUnit.SECONDS.sleep(1);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("1秒钟后出结果" + result);
return result;
}).whenComplete((v, e) -> {//没有异常,v是值,e是异常
if (e == null) {
System.out.println("------------------计算完成,更新系统updataValue" + v);
}
}).exceptionally(e -> {
e.printStackTrace();
System.out.println("异常情况" + e.getCause() + "\t" + e.getMessage());
return null;
});
//线程不要立刻结束,否则CompletableFuture默认使用的线程池会立刻关闭:暂停3秒钟线程
System.out.println(Thread.currentThread().getName()+"线程先去忙其他任务");
try {
TimeUnit.SECONDS.sleep(3);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
//ForkJoinPool.commonPool-worker-9----副线程come in
//main线程先去忙其他任务
//1秒钟后出结果7
//------------------计算完成,更新系统updataValue7
使用自定义线程池
public class CompletableFutureDemo3 {
public static void main(String[] args) throws ExecutionException, InterruptedException {
ExecutorService executorService = Executors.newFixedThreadPool(3);
CompletableFuture<Integer> exceptionally = CompletableFuture.supplyAsync(() -> {
System.out.println(Thread.currentThread().getName() + "----副线程come in");
int result = ThreadLocalRandom.current().nextInt(10);
try {
TimeUnit.SECONDS.sleep(1);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("1秒钟后出结果" + result);
return result;
},executorService).whenComplete((v, e) -> {//没有异常,v是值,e是异常
if (e == null) {
System.out.println("------------------计算完成,更新系统updataValue" + v);
}
}).exceptionally(e -> {
e.printStackTrace();
System.out.println("异常情况" + e.getCause() + "\t" + e.getMessage());
return null;
});
//线程不要立刻结束,否则CompletableFuture默认使用的线程池会立刻关闭:暂停3秒钟线程
System.out.println(Thread.currentThread().getName()+"线程先去忙其他任务");
// try {
// TimeUnit.SECONDS.sleep(3);
// } catch (InterruptedException e) {
// e.printStackTrace();
// }
}
1需求说明
1.1同一款产品,同时搜索出同款产品在各大电商平台的售价;
1.2同一款产品,同时搜索出本产品在同一个电商平台下,各个入驻卖家售价是多少2输出返回:
出来结果希望是同款产品的在不同地方的价格清单列表, 返回一个List
《mysql》in jd price is 88.05
《mysql》in dang dang price is 86.11
《mysql》in tao bao price is 90.433解决方案,比对同一个商品在各个平台上的价格,要求获得一个清单列表
1 step by step , 按部就班, 查完京东查淘宝, 查完淘宝查天猫…
2 all in ,万箭齐发,一口气多线程异步任务同时查询。。。
public class NetMall {
@Getter
private String netMallName;
public NetMall(String netMallName) {
this.netMallName = netMallName;
}
public double calcPrice(String productName){
try {
TimeUnit.SECONDS.sleep(1);
} catch (InterruptedException e) {
e.printStackTrace();
}
return ThreadLocalRandom.current().nextDouble()*20;//用这句话来模拟价格
}
}
public class Case {
static List<NetMall> list= Arrays.asList(
new NetMall("jd"),
new NetMall("dangdang"),
new NetMall("taobao")
);
public static List<String> getPrice(List<NetMall> list,String productName){
return list.stream()
.map(netMall -> String.format(productName+" in %s price is %.2f",
netMall.getNetMallName(),netMall.calcPrice(productName)))
.collect(Collectors.toList());
}
public static void main(String[] args) {
long startTime = System.currentTimeMillis();
List<String> list1 = getPrice(list, "mysql");
for(String element:list1){
System.out.println(element);
}
long endTime = System.currentTimeMillis();
System.out.println("---当前操作花费时间----costTime:"+(endTime-startTime)+"毫秒");
}
}
mysql in jd price is 16.61
mysql in dangdang price is 18.52
mysql in taobao price is 17.34
---当前操作花费时间----costTime:3081毫秒
//从功能到性能
public static List<String> getPricesByCompletableFuture(List<NetMall> list,String productName){
return list.stream().map(netMall -> CompletableFuture.supplyAsync(()-> String.format(productName+" in %s price is %.2f",
netMall.getNetMallName(),netMall.calcPrice(productName))))//Stream>
.collect(Collectors.toList())//List>
.stream()//Stream
.map(s->s.join())//Stream
.collect(Collectors.toList());
}
mysql in jd price is 14.32
mysql in dangdang price is 2.48
mysql in taobao price is 2.24
---当前操作花费时间----costTime:1060毫秒
public T get() 不见不散,容易阻塞
public T get(long timeout,TimeUnit unit) 过时不候,超过时间会爆异常
public T join() 类似于get(),区别在于是否需要抛出异常
public T getNow(T valueIfAbsent)
没有计算完成的情况下,给一个替代结果
立即获取结果不阻塞
计算完,返回计算完成后的结果
没算完,返回设定的valueAbsent(直接返回了备胎值xxx)
public boolean complete(T value) 是否立即打断get()方法返回括号值
public class CompletableFutureDemo4 {
public static void main(String[] args) throws InterruptedException, ExecutionException {
CompletableFuture<String> stringCompletableFuture = CompletableFuture.supplyAsync(() -> {
try {
TimeUnit.SECONDS.sleep(2);//执行需要2秒
} catch (InterruptedException e) {
e.printStackTrace();
}
return "abc";
});
TimeUnit.SECONDS.sleep(1);
// System.out.println(stringCompletableFuture.getNow("xxx"));//执2-等1 返回xxx
System.out.println(stringCompletableFuture.complete("completeValue")+"\t"+stringCompletableFuture.get());//true completableFuture
}
}
thenApply
计算结果存在在依赖关系,使得线程串行化。因为依赖关系,所以一旦有异常,直接叫停。public class CompletableFutureDemo4 {
public static void main(String[] args) throws InterruptedException, ExecutionException {
//当一个线程依赖另一个线程时用 thenApply 方法来把这两个线程串行化,
CompletableFuture<Integer> exceptionally = CompletableFuture.supplyAsync(() -> {
//暂停几秒线程
try {
TimeUnit.SECONDS.sleep(1);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("111");
return 1024;
}).thenApply(f -> {
// int age = 10/0;//异常语句
System.out.println("222");
return f + 1;
}).thenApply(f -> {
System.out.println("333");
return f + 1;
}).whenComplete((v, e) -> {
System.out.println("*****v: " + v);
}).exceptionally(e -> {
e.printStackTrace();
return null;
});
System.out.println("-----主线程结束,END");
// 主线程不要立刻结束,否则CompletableFuture默认使用的线程池会立刻关闭:
try { TimeUnit.SECONDS.sleep(2); } catch (InterruptedException e) { e.printStackTrace(); }
}
}
//-----正常情况
//111
//222
//333
//----计算结果: 1026
//-----异常情况
//111
//异常.....
handle
类似于thenApply,但是有异常的话仍然可以往下走一步。public class CompletableFutureDemo2
{
public static void main(String[] args) throws ExecutionException, InterruptedException
{
//当一个线程依赖另一个线程时用 handle 方法来把这两个线程串行化,
// 异常情况:有异常也可以往下一步走,根据带的异常参数可以进一步处理
CompletableFuture.supplyAsync(() -> {
//暂停几秒钟线程
try { TimeUnit.SECONDS.sleep(1); } catch (InterruptedException e) { e.printStackTrace(); }
System.out.println("111");
return 1024;
}).handle((f,e) -> {
int age = 10/0;//异常语句
System.out.println("222");
return f + 1;
}).handle((f,e) -> {
System.out.println("333");
return f + 1;
}).whenCompleteAsync((v,e) -> {
System.out.println("*****v: "+v);
}).exceptionally(e -> {
e.printStackTrace();
return null;
});
System.out.println("-----主线程结束,END");
// 主线程不要立刻结束,否则CompletableFuture默认使用的线程池会立刻关闭:
try { TimeUnit.SECONDS.sleep(2); } catch (InterruptedException e) { e.printStackTrace(); }
}
}
//-----异常情况
//111
//333
//异常,可以看到多走了一步333
public static void main(String[] args) throws ExecutionException, InterruptedException
{
CompletableFuture.supplyAsync(() -> {
return 1;
}).thenApply(f -> {
return f + 2;
}).thenApply(f -> {
return f + 3;
}).thenApply(f -> {
return f + 4;
}).thenAccept(r -> System.out.println(r));
}
//6
//消费一下,直接得到6
补充:Code之任务之间的顺序执行
thenRun
thenRun(Runnable runnable)
任务A执行完执行B,并且B不需要A的结果
thenAccept
thenAccept(Consumer action)
任务A执行完执行B,B需要A的结果,但是任务B无返回值
thenApply
thenApply(Function fn)
任务A执行完执行B,B需要A的结果,同时任务B有返回值
System.out.println(CompletableFuture.supplyAsync(() -> "resultA").thenRun(() -> {}).join());
//null
System.out.println(CompletableFuture.supplyAsync(() -> "resultA").thenAccept(resultA -> {}).join());
//resultA打印出来的 null因为没有返回值
System.out.println(CompletableFuture.supplyAsync(() -> "resultA").thenApply(resultA -> resultA + " resultB").join());
//resultAresultB 返回值
上面的几个方法都有普通版本和后面加Async的版本
以thenRun和thenRunAsync为例,有什么区别?
先看结论
没有传入自定义线程池,都用默认线程池ForkJoinPool
传入了一个自定义线程池如果你执行第一个任务的时候,传入了一个自定义线程池
调用thenRun方法执行第二个任务的时候,则第二个任务和第一个任务是用同一个线程池
调用thenRunAsync执行第二个任务的时候,则第一个任务使用的是你自己传入的线程池,第二个任务使用的是ForkJoin线程池也有可能处理太快,
系统优化切换原则,直接使用main线程处理(把sleep去掉)
//2-1
public class CompletableFutureAPIDemo {
public static void main(String[] args) throws ExecutionException, InterruptedException {
ExecutorService threadPool = Executors.newFixedThreadPool(5);
CompletableFuture<Void> completableFuture = CompletableFuture.supplyAsync(()->{
try {TimeUnit.MILLISECONDS.sleep(20);} catch (InterruptedException e) {e.printStackTrace();}
System.out.println("1号任务"+"\t"+Thread.currentThread().getName());
return "abcd";
},threadPool).thenRun(()->{
try {TimeUnit.MILLISECONDS.sleep(20);} catch (InterruptedException e) {e.printStackTrace();}
System.out.println("2号任务"+"\t"+Thread.currentThread().getName());
}).thenRun(()->{
try {TimeUnit.MILLISECONDS.sleep(20);} catch (InterruptedException e) {e.printStackTrace();}
System.out.println("3号任务"+"\t"+Thread.currentThread().getName());
}).thenRun(()->{
try {TimeUnit.MILLISECONDS.sleep(20);} catch (InterruptedException e) {e.printStackTrace();}
System.out.println("4号任务"+"\t"+Thread.currentThread().getName());
});
}
}
//1号任务 pool-1-thread-1
//2号任务 pool-1-thread-1
//3号任务 pool-1-thread-1
//4号任务 pool-1-thread-1
//2-2
public class CompletableFutureAPIDemo {
public static void main(String[] args) throws ExecutionException, InterruptedException {
ExecutorService threadPool = Executors.newFixedThreadPool(5);
CompletableFuture<Void> completableFuture = CompletableFuture.supplyAsync(()->{
try {TimeUnit.MILLISECONDS.sleep(20);} catch (InterruptedException e) {e.printStackTrace();}
System.out.println("1号任务"+"\t"+Thread.currentThread().getName());
return "abcd";
},threadPool).thenRunAsync(()->{
try {TimeUnit.MILLISECONDS.sleep(20);} catch (InterruptedException e) {e.printStackTrace();}
System.out.println("2号任务"+"\t"+Thread.currentThread().getName());
}).thenRun(()->{
try {TimeUnit.MILLISECONDS.sleep(20);} catch (InterruptedException e) {e.printStackTrace();}
System.out.println("3号任务"+"\t"+Thread.currentThread().getName());
}).thenRun(()->{
try {TimeUnit.MILLISECONDS.sleep(20);} catch (InterruptedException e) {e.printStackTrace();}
System.out.println("4号任务"+"\t"+Thread.currentThread().getName());
});
}
}
//1号任务 pool-1-thread-1
//2号任务 ForkJoinPool.commonPool-worker-9---这里另起炉灶重新调用了默认的ForkJoinPool
//3号任务 ForkJoinPool.commonPool-worker-9
//4号任务 ForkJoinPool.commonPool-worker-9
public class CompletableFutureAPIDemo {
public static void main(String[] args) throws ExecutionException, InterruptedException {
ExecutorService threadPool = Executors.newFixedThreadPool(5);
CompletableFuture<Void> completableFuture = CompletableFuture.supplyAsync(()->{
// try {TimeUnit.MILLISECONDS.sleep(20);} catch (InterruptedException e) {e.printStackTrace();}
System.out.println("1号任务"+"\t"+Thread.currentThread().getName());
return "abcd";
},threadPool).thenRun(()->{
// try {TimeUnit.MILLISECONDS.sleep(20);} catch (InterruptedException e) {e.printStackTrace();}
System.out.println("2号任务"+"\t"+Thread.currentThread().getName());
}).thenRun(()->{
// try {TimeUnit.MILLISECONDS.sleep(20);} catch (InterruptedException e) {e.printStackTrace();}
System.out.println("3号任务"+"\t"+Thread.currentThread().getName());
}).thenRun(()->{
//try {TimeUnit.MILLISECONDS.sleep(20);} catch (InterruptedException e) {e.printStackTrace();}
System.out.println("4号任务"+"\t"+Thread.currentThread().getName());
});
}
}
//1号任务 1号任务 pool-1-thread-1
//2号任务 main
//3号任务 main
//4号任务 main
public class CompletableFutureDemo2 {
public static void main(String[] args) throws ExecutionException, InterruptedException {
CompletableFuture<String> play1 = CompletableFuture.supplyAsync(() -> {
System.out.println(Thread.currentThread().getName() + "\t" + "---come in ");
//暂停几秒钟线程
try { TimeUnit.SECONDS.sleep(2); } catch (InterruptedException e) { e.printStackTrace(); }
return "play1 ";
});
CompletableFuture<String> play2 = CompletableFuture.supplyAsync(() -> {
System.out.println(Thread.currentThread().getName() + "\t" + "---come in ");
try { TimeUnit.SECONDS.sleep(1); } catch (InterruptedException e) { e.printStackTrace(); }
return "play2";
});
CompletableFuture<String> thenCombineResult = play1.applyToEither(play2, f -> {//对计算速度进行选用
return f + " is winner";
});
System.out.println(Thread.currentThread().getName() + "\t" + thenCombineResult.get());
}
}
//ForkJoinPool.commonPool-worker-9 ---come in
//ForkJoinPool.commonPool-worker-2 ---come in
//main play2 is winner
thenCombine 合并
两个CompletionStage任务都完成后,最终能把两个任务的结果一起交给thenCOmbine来处理
先完成的先等着,等待其它分支任务
public class CompletableFutureDemo2
{
public static void main(String[] args) throws ExecutionException, InterruptedException
{
CompletableFuture<Integer> completableFuture1 = CompletableFuture.supplyAsync(() -> {
System.out.println(Thread.currentThread().getName() + "\t" + "---come in ");
return 10;
});
CompletableFuture<Integer> completableFuture2 = CompletableFuture.supplyAsync(() -> {
System.out.println(Thread.currentThread().getName() + "\t" + "---come in ");
return 20;
});
CompletableFuture<Integer> thenCombineResult = completableFuture1.thenCombine(completableFuture2, (x, y) -> {
System.out.println(Thread.currentThread().getName() + "\t" + "---come in ");
return x + y;
});
System.out.println(thenCombineResult.get());
}
}
//30