两种创建CompletableFuture的方式:
①:CompletableFuture.supplyAsync(执行有返回值的方法)
CompletableFuture codeFuture = CompletableFuture.supplyAsync(() ->
loginService.getCode()
);
②:CompletableFuture.runAsync(执行无返回值的方法)
CompletableFuture nameFuture = CompletableFuture.runAsync(
() -> loginService.settingName()
);
CompletableFuture新特性:
①:JAVA8的CompletableFuture可以主动设置计算的结果值(也就是说可以主动结束线程阻塞)
public String getCode() {
return "1128";
}
CompletableFuture codeFuture = CompletableFuture.supplyAsync(() ->
loginService.getCode()
);
// 主动设置返回值
codeFuture.complete("wozhudongjieshu");
// 控制台打印返回值
System.out.println(codeFuture.join());
输出结果wozhudongjieshu
结论:同样道理,利用场景就是当线程发生阻塞时,可以利用利用另一个线程主动设置返回值
②:配合自定义线程池使用
CompletableFuture.supplyAsync有两个方法,如果不用自定义线程池,将自己用LinkedBlockingQueuen new一个线程池,根据业务需要,也可以用自己定义的线程池。
定义线程池:
@Bean("myExecutor")
public Executor myExecutor(){
// 活动线程数为20的线程池
return Executors.newFixedThreadPool(20);
}
把线程池放上去
@Autowired
@Qualifier("myExecutor")
Executor executor;
public void testAsyn() throws ExecutionException, InterruptedException {
CompletableFuture codeFuture = CompletableFuture.supplyAsync(() ->
loginService.getCode(),executor
);
}
③:异常抛到主线程中
如果此刻CompletableFuture.supplyAsync不去捕获异常的话,调用getCode这个方法时,异常就会被吞了。
CompletableFuture codeFuture = CompletableFuture.supplyAsync(() ->
loginService.getCode(),executor
);
public String getCode() {
throw new RuntimeException("fail");
}
此时如果想把异常抛到主线程的话就得用.excetionally
CompletableFuture codeFuture = CompletableFuture.supplyAsync(() ->
loginService.getCode(), executor
).exceptionally(e -> {
System.out.println(e);
throw new RuntimeException(e);
}
);
这样异常就在主线程捕获到了
java.lang.RuntimeException: fail
④:数据整合
//a任务
CompletableFuture<List<String>> listCompletableFuture = CompletableFuture
.supplyAsync(() -> publicService.add());
//b任务
CompletableFuture<List<String>> listCompletableFuture1 =
CompletableFuture.supplyAsync(()
-> domoService.mins()
);
//待a任务和b任务都完成,整合数据(.thenCombine)
List<String> join = listCompletableFuture
.thenCombine(listCompletableFuture1, (List<String> a, List<String> b) -> {
a.addAll(b);
System.out.println(System.currentTimeMillis());
return a;
}).join();