美文网首页Java
Java 8 的异步利器:CompletableFuture源码

Java 8 的异步利器:CompletableFuture源码

作者: 愿天堂没有BUG | 来源:发表于2022-08-18 11:19 被阅读0次

    completableFuture 是JDK1.8版本新引入的类。下面是这个类:

    实现了俩接口,本身是个class。这个是Future的实现类,使用 completionStage 接口去支持完成时触发的函数和操作。

    一个 completetableFuture 就代表了一个任务,他能用Future的方法,还能做一些之前说的 executorService 配合 futures 做不了的。

    之前future需要等待isDone为true才能知道任务跑完了,或者就是用get方法调用的时候会出现阻塞,而使用 completableFuture 的使用就可以用then,when等等操作来防止以上的阻塞和轮询isDone的现象出现。

    1.创建CompletableFuture直接new对象。

    一个 completableFuture 对象代表着一个任务,这个对象能跟这个任务产生联系。

    下面用的 complete 方法意思就是这个任务完成了需要返回的结果,然后用 get() 方法可以获取到。

    2.JDK1.8使用的接口类。

    在本文的 CompletableFuture 中大量地使用了这些函数式接口。

    注:这些声明大量应用于方法的入参中,像 thenApply 和 thenAccept 这俩就是一个用Function一个用Consumer

    而lambda函数正好是可以作为这些接口的实现。例如 s->{return 1;} 这个就相当于一个Function。因为有入参和返回结果。

    (1)Function

    (2)Consumer

    对于前面有Bi的就是这样的,BiConsumer就是两个参数的。

    (3)Predicate这个接口声明是一个入参,返回一个boolean。

    (4)supplier

    3.下面是这个类的静态方法

    带有Async就是异步执行的意思、也是一个 completableFuture 对象代表着一个任务这个原则。

    这种异步方法都可以指定一个线程池作为任务的运行环境,如果没有指定就会使用 ForkJoinPool 线程池来执行

    (1) supplyAsync&runAsync 的使用例子。

    publicstatic void main(String[] args) throws ExecutionException, InterruptedE

    这些任务中带有supply是持有返回值的,run是void返回值的,在玩supply时发现一个问题:如果使用supplyAsync任务时不使用任务的返回值,即 不用get方法阻塞主线程会导致任务执行中断。

    注:跟get方法无关,后面有答案

    然后我开始探索是否是只有 supplyAsync 是这样。我测试了 runAsync 发现也是这样。

    下图为与 supplyAsync 任务执行不全面一样的问题,我甚至测试了将lambda换成runnable发现无济于事。

    答案:

    造成这个原因是因为Daemon。因为 completableFuture 这套使用异步任务的操作都是创建成了守护线程,那么我们没有调用get方法不阻塞这个主线程的时候。主线程执行完毕,所有线程执行完毕就会导致一个问题,就是守护线程退出。

    那么我们没有执行的代码就是因为主线程不再跑任务而关闭导致的,可能这个不叫问题,因为在开发中我们主线程常常是一直开着的。但是这个小问题同样让我想了好久。

    相关文章

      网友评论

        本文标题:Java 8 的异步利器:CompletableFuture源码

        本文链接:https://www.haomeiwen.com/subject/zjfugrtx.html