CompletableFuture是用来描述多线程任务的时序关系的:串行关系,并行关系,聚合关系。java
CompletableFuture 是Java 8 新增长的Api,该类实现,Future和CompletionStage两个接口,提供了很是强大的Future的扩展功能,能够帮助咱们简化异步编程的复杂性,提供了函数式编程的能力,能够经过回调的方式处理计算结果,而且提供了转换和组合CompletableFuture的方法。编程
方式一:使用默认线程池多线程
/** * 建立一个不带返回值得任务。 */ CompletableFuture<Void> f1 = CompletableFuture.runAsync(new Runnable() { @Override public void run() { //业务逻辑 } }); /** * 建立一个带返回值的任务。 */ CompletableFuture<String> f2 = CompletableFuture.supplyAsync(new Supplier<String>() { @Override public String get() { //业务逻辑 return null; } });
方式二:使用自定义线程池(建议使用)app
//建立线程池 ExecutorService executor = Executors.newFixedThreadPool(10); //建立一个不带返回值得任务。 CompletableFuture<Void> f1 = CompletableFuture.runAsync(new Runnable() { @Override public void run() { } },executor); //建立一个带返回值的任务。 CompletableFuture<String> f2 = CompletableFuture.supplyAsync(new Supplier<String>() { @Override public String get() { //业务逻辑 return null; } },executor);
CompletionStage接口能够清晰地描述任务之间的这种时序关系,时序关系:串行,并行,汇聚。dom
线程与线程之间的执行顺序是串行的。异步
//Async表明的是异步执行fn CompletionStage<R> thenApply(fn); CompletionStage<R> thenApplyAsync(fn); CompletionStage<Void> thenAccept(consumer); CompletionStage<Void> thenAcceptAsync(consumer); CompletionStage<Void> thenRun(action); CompletionStage<Void> thenRunAsync(action); CompletionStage<R> thenCompose(fn); CompletionStage<R> thenComposeAsync(fn);
CompletionStage接口里面描述串行关系,主要是thenApply、thenAccept、thenRun和thenCompose这四 个系列的接口。ide
thenApply系列函数里参数fn的类型是接口Function<T,R>,这个接口里与CompletionStage相关的方法是R apply(T t),这个方法既能接收参数也支持返回值,因此thenApply系列方法返回的是CompletionStage<R>。函数式编程
而thenAccept系列方法里参数consumer的类型是接口Consumer<T>,这个接口里与CompletionStage相关 的方法是voidaccept(T t),这个方法虽然支持参数,但却不支持回值,因此thenAccept系列方法返回的是CompletionStage<Void>。异步编程
thenRun系列方法里action的参数是Runnable,因此action既不能接收参数也不支持返回值,因此thenRun 系列方法返回的也是CompletionStage<Void>。函数
这些方法里面Async表明的是异步执行fn、consumer或者action。其中,须要你注意的是thenCompose系列方法,这个系列的方法会新建立出一个子流程,最终结果和thenApply系列是相同的。
演示串行
//supplyAsync()启动一个异步 流程 CompletableFuture<String> f0 = CompletableFuture.supplyAsync( () -> "Hello World") //① .thenApply(s -> s + "girl") //② .thenApply(String::toUpperCase);//③ System.out.println(f0.join()); //输出结果 HELLO WORLD girl
虽然这是一个异步流程,但任务①②③倒是 串行执行的,②依赖①的执行结果,③依赖②的执行结果。
CompletionStage接口里面描述AND汇聚关系,主要是thenCombine、thenAcceptBoth和runAfterBoth系列的接口,这些接口的区别也是源自fn、consumer、action这三个核心参数不一样。
CompletionStage<R> thenCombine(other,fn); CompletionStage<R> thenCombineAsync(other,fn); CompletionStage<Void> thenAcceptBoth(other,consumer); CompletionStage<Void> thenAcceptBothAsync(other,consumer); CompletionStage<Void> runAfterBoth(other, action); CompletionStage<Void> runAfterBothAsync(other, action);
演示:
// 启动一个异步流程f1 CompletableFuture<Void> f1 = CompletableFuture.runAsync(()->{ System.out.println("异步任务-1"); }); // 启动一个异步流程f2 CompletableFuture<String> f2 = CompletableFuture.supplyAsync(()->{ String s = "异步任务-2"; System.out.println(s); return s; }); //启动一个汇聚流程f3 CompletableFuture<String> f3 = f1.thenCombine(f2,(a,tf)->{ return tf;//tf是f2的值 }); //等待任务3执行结果 System.out.println(f3.join());
CompletionStage接口里面描述OR汇聚关系,主要是applyToEither、acceptEither和runAfterEither系列的 接口,这些接口的区别也是源自fn、consumer、action这三个核心参数不一样。
CompletionStage applyToEither(other, fn); CompletionStage applyToEitherAsync(other, fn); CompletionStage acceptEither(other, consumer); CompletionStage acceptEitherAsync(other, consumer); CompletionStage runAfterEither(other, action); CompletionStage runAfterEitherAsync(other, action);
功能演示:
// 启动一个异步流程f1 CompletableFuture<String> f1 = CompletableFuture.supplyAsync(()->{ int t = new Random().nextInt(10); System.out.println("f1-t = "+t); sleep(t, TimeUnit.SECONDS); return String.valueOf(t); }); // 启动一个异步流程f2 CompletableFuture<String> f2 = CompletableFuture.supplyAsync(()->{ int t = new Random().nextInt(10); System.out.println("f2-t = "+t); sleep(t, TimeUnit.SECONDS); return String.valueOf(t); }); //将f1和f2的值汇总到f3 CompletableFuture<String> f3 = f1.applyToEither(f2,s -> Integer.parseInt(f2.join())+Integer.parseInt(s)+"" ); System.out.println(f3.join());
**** 码字不易若是对你有帮助请给个关注****
**** 爱技术爱生活 QQ群: 894109590****