听说你还不知道CompletableFuture?

<div class="output_wrapper" id="output_wrapper_id" style="font-size: 16px; color: rgb(62, 62, 62); line-height: 1.6; word-spacing: 0px; letter-spacing: 0px; font-family: ‘Helvetica Neue’, Helvetica, ‘Hiragino Sans GB’, ‘Microsoft YaHei’, Arial, sans-serif;"><p style="font-size: inherit; color: inherit; line-height: inherit; padding: 0px; margin: 1.5em 0px;">java8已经在日常开发编码中非常普遍了,掌握运用好它可以在开发中运用几行精简代码就可以完成所需功能。

今天将介绍CompletableFuture的在生产环境如何使用实践。CompletableFuture类作为Java 8 Concurrency API改进而引入,熟悉的同学应该了解在Java 9 也有对CompletableFuture有一些改进,橘子之后再进入讲解。

阅读这篇文章需要知道的前置知识点有,函数式编程线程池原理等。还不熟悉的同学可以看看之前的文章,话不多说,开始吧。</p>

<p style="font-size: inherit; color: inherit; line-height: inherit; padding: 0px; margin: 1.5em 0px;">为了更好的表达,我们结合例子讲解,假设今天小橘收到TL任务,要求完成实时拉取数据的功能,完成后告知拉取完成。假设拉取数据需要从A,B,C三个服务中获取,拉取完成推送需要调用D服务。</p>

<p style="font-size: inherit; color: inherit; line-height: inherit; padding: 0px; margin: 1.5em 0px;">需求变更1:拉取数据需要从E服务获取,但是会依赖从A服务获取的结果。

需求变更2:从A服务一次能拉去一万+数据,但是E服务的性能支撑不了大调用,在Provider端有限流兜底。

需求变更3:拉取数据过程中需要保证数据完整性,不能出现统计错误。</p>

<h4 id="hcompletablefuture" style="color: inherit; line-height: inherit; padding: 0px; margin: 1.5em 0px; font-weight: bold; font-size: 1.2em;"><span style="font-size: inherit; color: inherit; line-height: inherit; margin: 0px; padding: 0px;">为什么使用CompletableFuture</span></h4>

<p style="font-size: inherit; color: inherit; line-height: inherit; padding: 0px; margin: 1.5em 0px;">橘友们说了,这个可以用jdk5.0提供的Future<v style="font-size: inherit; color: inherit; line-height: inherit; margin: 0px; padding: 0px;">来实现,我们将拉取数据需要用到的从A,B ,C三个服务接口放到FutureTask中,异步的去执行获取数据结果,然后再同步调用D服务。

OK,简单实现这个功能没有问题,但是有什么缺陷,需要怎么可以改进嘛?

我们通过源码注释可以看到Future类返回的结果需要阻塞等待get方法返回结果,它提供了isDone()方法检测异步计算是否已经结束,get()方法等待异步操作结束,以及获取计算的结果。等到所有Future任务完成,通知线程获取结果并合并。</v></p>

<p style="font-size: inherit; color: inherit; line-height: inherit; padding: 0px; margin: 1.5em 0px;">从性能上,需要等待 Future 集合中的所有任务都完成(此需求没问题,接着往下看), 从健壮性上,Futrue接口没有方法去进行计算组合或者处理可能出现的错误。从功能扩展上,Future接口无法进行多个异步计算之间相互独立,同时第二个又依赖于第一个的结果。而今天的主角CompletableFuture都可以满足上述功能,具有大约50种不同的构成,结合,执行异步计算步骤和处理错误。(全部学习完所有方法是不现实的,掌握灵魂和核心方法即可依法炮制)</p>

<h4 id="hcompletablefutureapi" style="color: inherit; line-height: inherit; padding: 0px; margin: 1.5em 0px; font-weight: bold; font-size: 1.2em;"><span style="font-size: inherit; color: inherit; line-height: inherit; margin: 0px; padding: 0px;">CompletableFuture API 使用</span></h4>

<blockquote style="line-height: inherit; display: block; padding: 15px 15px 15px 1rem; font-size: 0.9em; margin: 1em 0px; color: rgb(129, 145, 152); border-left: 6px solid rgb(220, 230, 240); background: rgb(242, 247, 251); overflow: auto; overflow-wrap: normal; word-break: normal;">

<p style="font-size: inherit; color: inherit; line-height: inherit; padding: 0px; margin: 0px;">API太多,简单列举。读者自行学习即可,本文重点不在介绍api</p>

</blockquote>

<pre style="font-size: inherit; color: inherit; line-height: inherit; margin: 0px; padding: 0px;"> <span class="hljs-comment" style="font-size: inherit; line-height: inherit; margin: 0px; padding: 0px; color: rgb(136, 136, 136); word-wrap: inherit !important; word-break: inherit !important;">/
   任务 A 执行完执行 B,执行 B 不需要依赖 A 的结果同时 B 不返回结果。
/</span>
CompletableFuture.supplyAsync(() -> <span class="hljs-string" style="font-size: inherit; line-height: inherit; margin: 0px; padding: 0px; color: rgb(162, 252, 162); word-wrap: inherit !important; word-break: inherit !important;">"resultA"</span>).thenRun(() -> {}); 
<span class="hljs-comment" style="font-size: inherit; line-height: inherit; margin: 0px; padding: 0px; color: rgb(136, 136, 136); word-wrap: inherit !important; word-break: inherit !important;">/

   任务 A 执行完执行 B,B 执行依赖 A 结果同时 B 不返回结果
/</span>
CompletableFuture.supplyAsync(() -> <span class="hljs-string" style="font-size: inherit; line-height: inherit; margin: 0px; padding: 0px; color: rgb(162, 252, 162); word-wrap: inherit !important; word-break: inherit !important;">"resultA"</span>).thenAccept(resultA -> {});
<span class="hljs-comment" style="font-size: inherit; line-height: inherit; margin: 0px; padding: 0px; color: rgb(136, 136, 136); word-wrap: inherit !important; word-break: inherit !important;">/*
   任务 A 执行完执行 B,B 执行依赖 A 结果同时 B 返回结果
/</span>
CompletableFuture.supplyAsync(() -> <span class="hljs-string" style="font-size: inherit; line-height: inherit; margin: 0px; padding: 0px; color: rgb(162, 252, 162); word-wrap: inherit !important; word-break: inherit !important;">"resultA"</span>).thenApply(resultA -> resultA + <span class="hljs-string" style="font-size: inherit; line-height: inherit; margin: 0px; padding: 0px; color: rgb(162, 252, 162); word-wrap: inherit !important; word-break: inherit !important;">" resultB"</span>);

</pre>

<pre style="font-size: inherit; color: inherit; line-height: inherit; margin: 0px; padding: 0px;">

CompletableFuture completableFuture 
  = CompletableFuture.supplyAsync(() -> "orange")
    .thenCompose(s -> CompletableFuture.supplyAsync(() -> s + " csong"));
//true
assertEquals("orangecsong", completableFuture.get());

</pre>

<p style="font-size: inherit; color: inherit; line-height: inherit; padding: 0px; margin: 1.5em 0px;">你的疑问:该thenCompose方法不和thenApply一样实现结果合并计算嘛?</p>

<p style="font-size: inherit; color: inherit; line-height: inherit; padding: 0px; margin: 1.5em 0px;">刚学习时候确实有点迷惑,其实他们的内部形式是不一样的,它们与Java 8中可用的Stream和Optional类的map和flatMap方法是有着类似的设计思路在里面的。都是接收一个CompletableFuture并将其应用于计算结果,但thenCompose(flatMap)方法接收一个函数,该函数返回相同类型的另一个CompletableFuture对象。</p>

<pre style="font-size: inherit; color: inherit; line-height: inherit; margin: 0px; padding: 0px;">

CompletableFuture completableFuture 
  = CompletableFuture.supplyAsync(() -> "orange")
    .thenCombine(CompletableFuture.supplyAsync(
      () -> " chizongzi"), (s1, s2) -> s1 + s2));

assertEquals("orange chizongzi", completableFuture.get());

</pre>

<p style="font-size: inherit; color: inherit; line-height: inherit; padding: 0px; margin: 1.5em 0px;">thenCombine方法旨在当你想要使用多个计算结果时,而后续的处理同时需要依赖返回值,第一个计算结果返回 "orange",第二个计算结果返回 "chizongzi",对结果进行拼接,那么结果就是"orange chizongzi" 啦。你可能会问如果结果无需处理呢?thenAcceptBoth将可以实现你的功能。那么它和thenApply的区别又是啥呢?

thenCompose()方法是使用前一个Future作为参数。它会直接使结果变新的Future,而不是我们在thenApply()中到的嵌套Future,而是用来连接两个CompletableFuture,是生成一个新的CompletableFuture,因此,如果想要继续嵌套链接CompletableFuture 方法,那么最好使用thenCompose()。</p>

<pre style="font-size: inherit; color: inherit; line-height: inherit; margin: 0px; padding: 0px;">

public static CompletableFuture allOf(CompletableFuture... cfs){...}

</pre>

<p style="font-size: inherit; color: inherit; line-height: inherit; padding: 0px; margin: 1.5em 0px;">当我们需要并行执行多个任务时,我们通常希望等待所有它们执行,然后处理它们的组合结果。CompletableFuture提供了allOf静态方法允许等待所有的完成任务,但是它返回类型是CompletableFuture 。局限性在于它不会返回所有任务的综合结果。相反,你必须手动从Futures获取结果。那么怎么解决呢,CompletableFuture提供了join()可以解决,这里小橘用Stream实现同样可以的。</p>

<pre style="font-size: inherit; color: inherit; line-height: inherit; margin: 0px; padding: 0px;">

String multiFutures= Stream.of(future1, future2, future3)
  .map(CompletableFuture::join)
  .collect(Collectors.joining(" "));

assertEquals("Today is sun", multiFutures);

</pre>

<p style="font-size: inherit; color: inherit; line-height: inherit; padding: 0px; margin: 1.5em 0px;">那么 CompletableFuture 针对异常是如何处理的呢?</p>

<pre style="font-size: inherit; color: inherit; line-height: inherit; margin: 0px; padding: 0px;">

public CompletableFuture exceptionally(Function fn);
public  CompletionStage handle(BiFunctionsuper T, Throwable, ? extends U> fn);

</pre>

<pre style="font-size: inherit; color: inherit; line-height: inherit; margin: 0px; padding: 0px;">

CompletableFuture.supplyAsync(() -> "resultA")
    .thenApply(resultA -> resultA + " resultB")
    .thenApply(resultB -> resultB + " resultC")

//如果resultA,resultB,resultC在获取中有异常

CompletableFuture future = CompletableFuture.supplyAsync(() -> {
    throw new RuntimeException();
}).exceptionally(ex -> "errorResultA")
  .thenApply(resultA -> resultA + " resultB")
  .thenApply(resultB -> resultB + " resultC")

</pre>

<p style="font-size: inherit; color: inherit; line-height: inherit; padding: 0px; margin: 1.5em 0px;">上面的代码中,任务 A 抛出异常,然后通过exceptionally() 方法处理了异常,并返回新的结果,这个新的结果将传递给任务 B。如果inovke future.join方法结果将会输出 "errorResultA resultB result C"</p>

<p style="font-size: inherit; color: inherit; line-height: inherit; padding: 0px; margin: 1.5em 0px;"> 上述方法基本就是底层函数式api的使用,聪明的橘友们实践起来吧!
</p>

<h4 id="hcompletablefuture-1" style="color: inherit; line-height: inherit; padding: 0px; margin: 1.5em 0px; font-weight: bold; font-size: 1.2em;"><span style="font-size: inherit; color: inherit; line-height: inherit; margin: 0px; padding: 0px;">CompletableFuture 例子</span></h4>

<p style="font-size: inherit; color: inherit; line-height: inherit; padding: 0px; margin: 1.5em 0px;">Talk is cheap , show me code。自从上篇 你还在担心rpc接口超时吗 文章末尾讲述大批量调用,其中是顺序invoke调用,其实我们分析,异步调用利用CompletableFuture需要怎么实现呢?</p>

<pre style="font-size: inherit; color: inherit; line-height: inherit; margin: 0px; padding: 0px;"> <span class="hljs-comment" style="font-size: inherit; line-height: inherit; margin: 0px; padding: 0px; color: rgb(136, 136, 136); word-wrap: inherit !important; word-break: inherit !important;">/
  <span class="hljs-doctag" style="font-size: inherit; color: inherit; line-height: inherit; margin: 0px; padding: 0px; word-wrap: inherit !important; word-break: inherit !important;">@Description</span>:
 
 <span class="hljs-doctag" style="font-size: inherit; color: inherit; line-height: inherit; margin: 0px; padding: 0px; word-wrap: inherit !important; word-break: inherit !important;">@author</span>: orangeCs
  <span class="hljs-doctag" style="font-size: inherit; color: inherit; line-height: inherit; margin: 0px; padding: 0px; word-wrap: inherit !important; word-break: inherit !important;">@create</span>: 2020-06-25
 
/</span>
<span class="hljs-keyword" style="font-size: inherit; line-height: inherit; margin: 0px; padding: 0px; color: rgb(252, 194, 140); word-wrap: inherit !important; word-break: inherit !important;">public</span> <span class="hljs-class" style="font-size: inherit; color: inherit; line-height: inherit; margin: 0px; padding: 0px; word-wrap: inherit !important; word-break: inherit !important;"><span class="hljs-keyword" style="font-size: inherit; line-height: inherit; margin: 0px; padding: 0px; color: rgb(252, 194, 140); word-wrap: inherit !important; word-break: inherit !important;">class</span> <span class="hljs-title" style="font-size: inherit; line-height: inherit; margin: 0px; padding: 0px; color: rgb(255, 255, 170); word-wrap: inherit !important; word-break: inherit !important;">AsyncInvokeUtil</span> </span>{

    <span class="hljs-keyword" style="font-size: inherit; line-height: inherit; margin: 0px; padding: 0px; color: rgb(252, 194, 140); word-wrap: inherit !important; word-break: inherit !important;">private</span> AsyncInvokeUtil() {}

    <span class="hljs-comment" style="font-size: inherit; line-height: inherit; margin: 0px; padding: 0px; color: rgb(136, 136, 136); word-wrap: inherit !important; word-break: inherit !important;">/
      <span class="hljs-doctag" style="font-size: inherit; color: inherit; line-height: inherit; margin: 0px; padding: 0px; word-wrap: inherit !important; word-break: inherit !important;">@param</span> paramList 源数据 (需处理数据载体)
     
 <span class="hljs-doctag" style="font-size: inherit; color: inherit; line-height: inherit; margin: 0px; padding: 0px; word-wrap: inherit !important; word-break: inherit !important;">@param</span> buildParam 中转函数 (获取的结果做一层trans,来满足调用服务条件)
      <span class="hljs-doctag" style="font-size: inherit; color: inherit; line-height: inherit; margin: 0px; padding: 0px; word-wrap: inherit !important; word-break: inherit !important;">@param</span> transParam 中转函数 (获取的结果做一层trans,来满足调用服务条件)
     
 <span class="hljs-doctag" style="font-size: inherit; color: inherit; line-height: inherit; margin: 0px; padding: 0px; word-wrap: inherit !important; word-break: inherit !important;">@param</span> processFunction 中转处理函数
      <span class="hljs-doctag" style="font-size: inherit; color: inherit; line-height: inherit; margin: 0px; padding: 0px; word-wrap: inherit !important; word-break: inherit !important;">@param</span> size 分批大小
     
 <span class="hljs-doctag" style="font-size: inherit; color: inherit; line-height: inherit; margin: 0px; padding: 0px; word-wrap: inherit !important; word-break: inherit !important;">@param</span> executorService 暴露外部自定义实现线程池(demo没判空,可以做成非必传)
      <span class="hljs-doctag" style="font-size: inherit; color: inherit; line-height: inherit; margin: 0px; padding: 0px; word-wrap: inherit !important; word-break: inherit !important;">@param</span> <R>
     
 <span class="hljs-doctag" style="font-size: inherit; color: inherit; line-height: inherit; margin: 0px; padding: 0px; word-wrap: inherit !important; word-break: inherit !important;">@param</span> <T>
      <span class="hljs-doctag" style="font-size: inherit; color: inherit; line-height: inherit; margin: 0px; padding: 0px; word-wrap: inherit !important; word-break: inherit !important;">@param</span> <P>
     
 <span class="hljs-doctag" style="font-size: inherit; color: inherit; line-height: inherit; margin: 0px; padding: 0px; word-wrap: inherit !important; word-break: inherit !important;">@param</span> <k>
      <span class="hljs-doctag" style="font-size: inherit; color: inherit; line-height: inherit; margin: 0px; padding: 0px; word-wrap: inherit !important; word-break: inherit !important;">@return</span>
     
 <span class="hljs-doctag" style="font-size: inherit; color: inherit; line-height: inherit; margin: 0px; padding: 0px; word-wrap: inherit !important; word-break: inherit !important;">@throws</span> ExecutionException
      <span class="hljs-doctag" style="font-size: inherit; color: inherit; line-height: inherit; margin: 0px; padding: 0px; word-wrap: inherit !important; word-break: inherit !important;">@throws</span> InterruptedException
     
/</span>
    <span class="hljs-keyword" style="font-size: inherit; line-height: inherit; margin: 0px; padding: 0px; color: rgb(252, 194, 140); word-wrap: inherit !important; word-break: inherit !important;">public</span> <span class="hljs-keyword" style="font-size: inherit; line-height: inherit; margin: 0px; padding: 0px; color: rgb(252, 194, 140); word-wrap: inherit !important; word-break: inherit !important;">static</span> <R, T, P, k> <span class="hljs-keyword" style="font-size: inherit; line-height: inherit; margin: 0px; padding: 0px; color: rgb(252, 194, 140); word-wrap: inherit !important; word-break: inherit !important;">List</span><R> partitionAsyncInvokeWithRes(<span class="hljs-keyword" style="font-size: inherit; line-height: inherit; margin: 0px; padding: 0px; color: rgb(252, 194, 140); word-wrap: inherit !important; word-break: inherit !important;">List</span><T> paramList,
                                                                      <span class="hljs-function" style="font-size: inherit; color: inherit; line-height: inherit; margin: 0px; padding: 0px; word-wrap: inherit !important; word-break: inherit !important;"><span class="hljs-keyword" style="font-size: inherit; line-height: inherit; margin: 0px; padding: 0px; color: rgb(252, 194, 140); word-wrap: inherit !important; word-break: inherit !important;">Function</span><<span class="hljs-title" style="font-size: inherit; line-height: inherit; margin: 0px; padding: 0px; color: rgb(255, 255, 170); word-wrap: inherit !important; word-break: inherit !important;">List</span><<span class="hljs-title" style="font-size: inherit; line-height: inherit; margin: 0px; padding: 0px; color: rgb(255, 255, 170); word-wrap: inherit !important; word-break: inherit !important;">T</span>>, <span class="hljs-title" style="font-size: inherit; line-height: inherit; margin: 0px; padding: 0px; color: rgb(255, 255, 170); word-wrap: inherit !important; word-break: inherit !important;">P</span>> <span class="hljs-title" style="font-size: inherit; line-height: inherit; margin: 0px; padding: 0px; color: rgb(255, 255, 170); word-wrap: inherit !important; word-break: inherit !important;">buildParam</span>,
                                                                      <span class="hljs-title" style="font-size: inherit; line-height: inherit; margin: 0px; padding: 0px; color: rgb(255, 255, 170); word-wrap: inherit !important; word-break: inherit !important;">Function</span><<span class="hljs-title" style="font-size: inherit; line-height: inherit; margin: 0px; padding: 0px; color: rgb(255, 255, 170); word-wrap: inherit !important; word-break: inherit !important;">P</span>, <span class="hljs-title" style="font-size: inherit; line-height: inherit; margin: 0px; padding: 0px; color: rgb(255, 255, 170); word-wrap: inherit !important; word-break: inherit !important;">List</span><<span class="hljs-title" style="font-size: inherit; line-height: inherit; margin: 0px; padding: 0px; color: rgb(255, 255, 170); word-wrap: inherit !important; word-break: inherit !important;">k</span>>> <span class="hljs-title" style="font-size: inherit; line-height: inherit; margin: 0px; padding: 0px; color: rgb(255, 255, 170); word-wrap: inherit !important; word-break: inherit !important;">transParam</span>,
                                                                      <span class="hljs-title" style="font-size: inherit; line-height: inherit; margin: 0px; padding: 0px; color: rgb(255, 255, 170); word-wrap: inherit !important; word-break: inherit !important;">Function</span><<span class="hljs-title" style="font-size: inherit; line-height: inherit; margin: 0px; padding: 0px; color: rgb(255, 255, 170); word-wrap: inherit !important; word-break: inherit !important;">List</span><<span class="hljs-title" style="font-size: inherit; line-height: inherit; margin: 0px; padding: 0px; color: rgb(255, 255, 170); word-wrap: inherit !important; word-break: inherit !important;">k</span>>,<span class="hljs-title" style="font-size: inherit; line-height: inherit; margin: 0px; padding: 0px; color: rgb(255, 255, 170); word-wrap: inherit !important; word-break: inherit !important;">List</span><<span class="hljs-title" style="font-size: inherit; line-height: inherit; margin: 0px; padding: 0px; color: rgb(255, 255, 170); word-wrap: inherit !important; word-break: inherit !important;">R</span>>> <span class="hljs-title" style="font-size: inherit; line-height: inherit; margin: 0px; padding: 0px; color: rgb(255, 255, 170); word-wrap: inherit !important; word-break: inherit !important;">processFunction</span>,
                                                                      <span class="hljs-title" style="font-size: inherit; line-height: inherit; margin: 0px; padding: 0px; color: rgb(255, 255, 170); word-wrap: inherit !important; word-break: inherit !important;">Integer</span> <span class="hljs-title" style="font-size: inherit; line-height: inherit; margin: 0px; padding: 0px; color: rgb(255, 255, 170); word-wrap: inherit !important; word-break: inherit !important;">size</span>,
                                                                      <span class="hljs-title" style="font-size: inherit; line-height: inherit; margin: 0px; padding: 0px; color: rgb(255, 255, 170); word-wrap: inherit !important; word-break: inherit !important;">ExecutorService</span> <span class="hljs-title" style="font-size: inherit; line-height: inherit; margin: 0px; padding: 0px; color: rgb(255, 255, 170); word-wrap: inherit !important; word-break: inherit !important;">executorService</span>) <span class="hljs-title" style="font-size: inherit; line-height: inherit; margin: 0px; padding: 0px; color: rgb(255, 255, 170); word-wrap: inherit !important; word-break: inherit !important;">throws</span> <span class="hljs-title" style="font-size: inherit; line-height: inherit; margin: 0px; padding: 0px; color: rgb(255, 255, 170); word-wrap: inherit !important; word-break: inherit !important;">ExecutionException</span>, <span class="hljs-title" style="font-size: inherit; line-height: inherit; margin: 0px; padding: 0px; color: rgb(255, 255, 170); word-wrap: inherit !important; word-break: inherit !important;">InterruptedException</span> </span>{
        <span class="hljs-keyword" style="font-size: inherit; line-height: inherit; margin: 0px; padding: 0px; color: rgb(252, 194, 140); word-wrap: inherit !important; word-break: inherit !important;">List</span><CompletableFuture<<span class="hljs-keyword" style="font-size: inherit; line-height: inherit; margin: 0px; padding: 0px; color: rgb(252, 194, 140); word-wrap: inherit !important; word-break: inherit !important;">List</span><R>>> completableFutures = Lists.partition(paramList, size).stream()
                .map(buildParam)
                .map(transParam)
                .map(eachList -> CompletableFuture.supplyAsync(() ->
                        processFunction.apply(eachList), executorService))
                .collect(Collectors.toList());
        <span class="hljs-comment" style="font-size: inherit; line-height: inherit; margin: 0px; padding: 0px; color: rgb(136, 136, 136); word-wrap: inherit !important; word-break: inherit !important;">//get</span>
        CompletableFuture<Void> finishCompletableFuture = CompletableFuture.allOf(completableFutures.toArray(<span class="hljs-keyword" style="font-size: inherit; line-height: inherit; margin: 0px; padding: 0px; color: rgb(252, 194, 140); word-wrap: inherit !important; word-break: inherit !important;">new</span> CompletableFuture[<span class="hljs-number" style="font-size: inherit; line-height: inherit; margin: 0px; padding: 0px; color: rgb(211, 99, 99); word-wrap: inherit !important; word-break: inherit !important;">0</span>]));
        finishCompletableFuture.get();
        <span class="hljs-keyword" style="font-size: inherit; line-height: inherit; margin: 0px; padding: 0px; color: rgb(252, 194, 140); word-wrap: inherit !important; word-break: inherit !important;">return</span> completableFutures.stream().map(CompletableFuture::join)
                .filter(Objects::nonNull).reduce(<span class="hljs-keyword" style="font-size: inherit; line-height: inherit; margin: 0px; padding: 0px; color: rgb(252, 194, 140); word-wrap: inherit !important; word-break: inherit !important;">new</span> ArrayList<>(), (resList1, resList2) -> {
                    resList1.addAll(resList2);
                    <span class="hljs-keyword" style="font-size: inherit; line-height: inherit; margin: 0px; padding: 0px; color: rgb(252, 194, 140); word-wrap: inherit !important; word-break: inherit !important;">return</span> resList1;
                });
    }

}       

</pre>

<p style="font-size: inherit; color: inherit; line-height: inherit; padding: 0px; margin: 1.5em 0px;">仅仅这一篇文章是不够的,任何知识都是长期积累,反复思考才能变成自己的东西,在浮躁的社会,我们年轻人切勿浮躁,今天介绍到这里了,喜欢博主的朋友们记得点个关注哦。 </p></div>

本文由博客群发一文多发等运营工具平台 OpenWrite
发布

原文 

https://segmentfault.com/a/1190000023096245

本站部分文章源于互联网,本着传播知识、有益学习和研究的目的进行的转载,为网友免费提供。如有著作权人或出版方提出异议,本站将立即删除。如果您对文章转载有任何疑问请告之我们,以便我们及时纠正。

PS:推荐一个微信公众号: askHarries 或者qq群:474807195,里面会分享一些资深架构师录制的视频录像:有Spring,MyBatis,Netty源码分析,高并发、高性能、分布式、微服务架构的原理,JVM性能优化这些成为架构师必备的知识体系。还能领取免费的学习资源,目前受益良多

转载请注明原文出处:Harries Blog™ » 听说你还不知道CompletableFuture?

赞 (0)
分享到:更多 ()

评论 0

  • 昵称 (必填)
  • 邮箱 (必填)
  • 网址
© 2020 Harries Blog™   @版权所有 备案号: 京ICP备14030975号-1 | 网站标签| 网站地图