神奇,你居然还不会用CompletableFuture

Future机制在一定程度上都无法快速地满足以上需求,CompletableFuture便应运而生了。

本片会介绍CompletableFuture的api,并用一些示例演示如何去使用。

创建一个异步任务


  1. public static <U> CompletableFuture<U> supplyAsync(Supplier<U> supplier) 
  2.  
  3.  public static <U> CompletableFuture<U> supplyAsync(Supplier<U> supplier,Executor executor); 
  4.  
  5.  public static CompletableFuture<Void> runAsync(Runnable runnable); 
  6.  
  7.  public static CompletableFuture<Void> runAsync(Runnable runnable,Executor executor); 

supplyAsync与runAsync的区别在于:supplyAsync有返回值,而runAsync没有返回值

带Executor参数的构造函数,则使用线程池中的线程执行异步任务(线程池可以参考说说线程池)

不带Executor参数的构造函数,则使用ForkJoinPool.commonPool()中的线程执行异步任务(Fork/Join框架可以参考谈谈并行流parallelStream)

示例:使用supplyAsync创建一个有返回值的异步任务


  1. public class Case1 { 
  2.  
  3.     public static void main(String[] args) throws Exception { 
  4.  
  5.         CompletableFuture<Integer> completableFuture=CompletableFuture.supplyAsync(()->{ 
  6.             try { 
  7.                 Thread.sleep(1000); 
  8.             } catch (InterruptedException e) { 
  9.                 e.printStackTrace(); 
  10.             } 
  11.             return 1; 
  12.         }); 
  13.         //该方法会一直阻塞 
  14.         Integer result = completableFuture.get(); 
  15.         System.out.println(result); 
  16.     } 
  17.  

异步任务的回调


  1. public CompletableFuture<T> whenComplete(BiConsumer<? super T, ? super Throwable> action); 
  2.  
  3.   public CompletableFuture<T> whenCompleteAsync(BiConsumer<? super T, ? super Throwable> action); 
  4.  
  5.   public CompletableFuture<T> whenCompleteAsync(BiConsumer<? super T, ? super Throwable> action, Executor executor); 
  6.  
  7.   public CompletableFuture<T> exceptionally(Function<Throwable, ? extends T> fn); 

whenComplete开头的方法在计算任务完成(包括正常完成与出现异常)之后会回调

而exceptionally则只会在计算任务出现异常时才会被回调

如何确定哪个线程去回调whenComplete,比较复杂,先略过。

而回调whenCompleteAsync的线程比较简单,随便拿一个空闲的线程即可,后缀是Async的方法同理。

示例:计算出现异常,使用whenComplete与exceptionally进行处理


  1. package com.qcy.testCompleteableFuture; 
  2.  
  3. import java.util.concurrent.CompletableFuture; 
  4. import java.util.concurrent.ExecutionException; 
  5. import java.util.function.BiConsumer; 
  6. import java.util.function.Function
  7. import java.util.stream.IntStream; 
  8.  
  9. /** 
  10.  * @author qcy 
  11.  * @create 2020/09/07 17:40:44 
  12.  */ 
  13. public class Case2 { 
  14.  
  15.     public static void main(String[] args) throws Exception { 
  16.  
  17.         CompletableFuture<Integer> completableFuture = CompletableFuture.supplyAsync(() -> { 
  18.             try { 
  19.                 Thread.sleep(1000); 
  20.             } catch (InterruptedException e) { 
  21.                 e.printStackTrace(); 
  22.             } 
  23.             System.out.println("执行supplyAsync的线程:" + Thread.currentThread().getName()); 
  24.             int i = 1 / 0; 
  25.             return 1; 
  26.         }); 
  27.  
  28.         completableFuture.whenComplete(new BiConsumer<Integer, Throwable>() { 
  29.             @Override 
  30.             public void accept(Integer integer, Throwable throwable) { 
  31.                 System.out.println("执行whenComplete的线程:" + Thread.currentThread().getName()); 
  32.                 if (throwable == null) { 
  33.                     System.out.println("计算未出现异常,结果:" + integer); 
  34.                 } 
  35.             } 
  36.         }); 
  37.  
  38.         completableFuture.exceptionally(new Function<Throwable, Integer>() { 
  39.             @Override 
  40.             public Integer apply(Throwable throwable) { 
  41.                 //出现异常时,则返回一个默认值 
  42.                 System.out.println("计算出现异常,信息:" + throwable.getMessage()); 
  43.                 return -1; 
  44.             } 
  45.         }); 
  46.  
  47.         System.out.println(completableFuture.get()); 
  48.     } 
  49.  
【声明】:芜湖站长网内容转载自互联网,其相关言论仅代表作者个人观点绝非权威,不代表本站立场。如您发现内容存在版权问题,请提交相关链接至邮箱:bqsm@foxmail.com,我们将及时予以处理。

相关文章