1.简介
CompletableFuture 是 JDK8 提供的一个异步执行工具。
示例1:
publicstaticvoidmain(String[] args)throws ExecutionException, InterruptedException{
CompletableFuture<Void> future= CompletableFuture.runAsync(()->{for(int i=0; i<3; i++){
System.out.println(i);try{
Thread.sleep(1000L);}catch(InterruptedException ignored){}}
System.out.println("Future Finished.");});
System.out.println("Main Thread Finished.");
future.get();}
输出结果1:
2.异步执行
CompletableFuture 提供了两个方法用于异步执行:
- CompletableFuture.runAsync,
没有返回值
;- CompletableFuture.supplyAsync,
有返回值
。
示例:
publicstaticvoidmain(String[] args)throws ExecutionException, InterruptedException{// runAsync 没有返回值
CompletableFuture<Void> future1= CompletableFuture.runAsync(()-> System.out.println("future1 executed."));// supplyAsync 有返回值
CompletableFuture<Object> future2= CompletableFuture.supplyAsync(()->{
System.out.println("future2 executed.");return"result";});
System.out.println("future1.get(): "+ future1.get());
System.out.println("future2.get(): "+ future2.get());}
输出结果:
3.守护线程
CompletableFuture返回的Future默认为
守护线程
,如果不调用get()获取结果,主线程结束后会自动结束
。主要有以下4种情景:
- 情景1: 执行时间 > 主线程时间,异步线程
会执行
;- 情景2: 执行时间 > 主线程,是守护线程,会被杀死,异步线程
不会执行
;- 情景3: 执行时间 > 主线程,但是不是守护线程,不会被杀死,异步线程
会执行
;- 情景4: ExecutorService.submit(),默认不是守护线程,不会被杀死,异步线程
会执行
。
示例:
publicstaticvoidmain(String[] args){
ExecutorService executorService= Executors.newFixedThreadPool(2);// 1.执行时间 < 主线程,会打印
CompletableFuture<Void> future1= CompletableFuture.runAsync(()->
System.out.println("Thread1 是否为守护线程 : "+ Thread.currentThread().isDaemon()));// 2.执行时间 > 主线程,是守护线程,会被杀死,不会打印
CompletableFuture.runAsync(()->{try{
Thread.sleep(3000L);
System.out.println("Thread2 是否为守护线程 : "+ Thread.currentThread().isDaemon());}catch(InterruptedException e){
e.printStackTrace();}});// 3.执行时间 > 主线程,但是不是守护线程,不会被杀死,会打印
CompletableFuture.runAsync(()->{try{
Thread.sleep(1000L);
System.out.println("Thread3 等待1秒");
System.out.println("Thread3 是否为守护线程 : "+ Thread.currentThread().isDaemon());}catch(InterruptedException e){
e.printStackTrace();}}, executorService);// 4.ExecutorService.submit(),默认不是守护线程,不会被杀死,会打印。
executorService.submit(()->{try{
Thread.sleep(2000L);
System.out.println("Thread4 等待2秒");
System.out.println("Thread4 是否为守护线程 : "+ Thread.currentThread().isDaemon());}catch(InterruptedException e){
e.printStackTrace();}});// 主线程执行完毕
System.out.println("Main Thread Finished.");
executorService.shutdown();}
输出结果2:
4.处理执行结果
CompletableFuture还封装了很多
处理执行结果
操作。操作太多,列举比较常用的几种:
- thenAccept(): 对结果进行使用;
- thenApply(): 对结果进行转换;
- exceptionally(): 对异常进行处理;
- whenComplete(): 相当于 thenAccept() + thenApply() + exceptionally().
示例:
publicstaticvoidmain(String[] args){// thenAccept对结果进行使用
System.out.println("------------------------------");
CompletableFuture.supplyAsync(()->"Thread1 Finished.").thenAccept(System.out::println);// thenApply对结果进行转换
System.out.println("------------------------------");
CompletableFuture.supplyAsync(()->"Thread2 Finished.").thenApply(s-> s+" + thenApply()").thenAccept(System.out::println);// exceptionally对异常进行处理
System.out.println("------------------------------");
CompletableFuture.supplyAsync(()->{thrownewRuntimeException("Thread3 Failed.");}).exceptionally(Throwable::toString).thenAccept(System.out::println);// 主线程执行完毕
System.out.println("------------------------------");
System.out.println("Main Thread Finished.");}
输出结果:
whenComplete() 示例:
publicstaticvoidmain(String[] args)throws ExecutionException, InterruptedException{// thenAccept对结果进行使用
System.out.println("------------------------------");
CompletableFuture<String> future= CompletableFuture.supplyAsync(()->"Thread1 Finished.").whenComplete(newBiConsumer<String, Throwable>(){@Overridepublicvoidaccept(String s, Throwable throwable){
System.out.println("result: "+ s);
System.out.println("throwable: "+ throwable);}});// exceptionally对异常进行处理
System.out.println("------------------------------");
CompletableFuture.supplyAsync(()->{thrownewRuntimeException("Thread3 Failed.");}).whenComplete(newBiConsumer<Object, Throwable>(){@Overridepublicvoidaccept(Object s, Throwable throwable){
System.out.println("result: "+ s);
System.out.println("throwable: "+ throwable);}});
System.out.println("------------------------------");
System.out.println("future.get(): "+ future.get());// 主线程执行完毕
System.out.println("------------------------------");
System.out.println("Main Thread Finished.");}
输出结果:
整理完毕,完结撒花~