CompletableFuture的简单使用

日常开发中,我们都会用到线程池,一般会用execute()和submit()方法提交任务。但是当你用过CompletableFuture之后,就会发现以前的线程池处理任务有多难用,功能有多简陋,CompletableFuture又是多么简洁优雅。

要知道CompletableFuture已经随着Java8发布7年了,还没有过它就有点说不过去了。

一、线程池处理任务和CompletableFuture处理任务

输出结果:

这里能够发现两个问题:

有没有具体的优化方案呢?当然有了,请出来我们今天的主角CompletableFuture

输出结果:

可以看到是ComparableFutrue是通过supplyAsync方法进行异步执行任务的。

=============================================================

可是上面的任务执行还是有一些问题的,需要阻塞当前线程输出结果,但是我们并不能确定线程的执行结束时间。也就无法准确设置线程阻塞时间,这样子就会导致最后执行的结果不对。

我们可以通过join进行优化一下:异步任务完成时统一返回结果值

代码中使用了CompletableFuture的两个方法:

supplyAsync()方法作用是提交异步任务,有两个传参,任务和自定义线程池。
whenCompleteAsync()方法作用是异步获取结果,也有两个传参,结果和异常信息。

代码经过CompletableFuture改造后,是多么的简洁优雅。

提交任务也不用再关心线程池是怎么使用了,获取结果也不用再阻塞当前线程了。

==============================================================

又或者可以通过Java8的Stream流进进一步简化test2的代码:

二、CompletableFuture更多使用

第一种:使用CountDownLatch方式

第二种:使用CompletableFuture

打印结果:

这里需要说明的一点是,我这边使用了 CopyOnWriteArrayList,因为是在多线程环境下,如果使用ArrayList会导致有数据无法成功添加到集合中。

代码看着有点乱,其实逻辑很清晰。

CompletableFuture的 allOf()方法的作用就是,等待所有任务处理完成。

如果要实现这样一个需求,往线程池提交一批任务,只要有其中一个任务处理完成就返回。

该怎么做?如果你手动实现这个逻辑的话,代码肯定复杂且低效,有了CompletableFuture就非常简单了,只需调用 anyOf()方法就行了

执行结果:

执行结果:

代码主要用到了CompletableFuture的 thenApplyAsync()方法,作用就是异步处理上一个线程的结果。

三、CompletableFuture常用API

提交任务:

  • supplyAsync
  • runAsync

接力处理:

  • thenRun thenRunAsync
  • thenAccept thenAcceptAsync
  • thenApply thenApplyAsync
  • handle handleAsync
  • applyToEither applyToEitherAsync
  • acceptEither acceptEitherAsync
  • runAfterEither runAfterEitherAsync
  • thenCombine thenCombineAsync
  • thenAcceptBoth thenAcceptBothAsync

获取结果:

  • join 阻塞等待,不会抛异常
  • get 阻塞等待,会抛异常
  • complete(T value) 不阻塞,如果任务已完成,返回处理结果。如果没完成,则返回传参value。
  • completeExceptionally(Throwable ex) 不阻塞,如果任务已完成,返回处理结果。如果没完成,抛异常。

总结分类

run的方法, 无入参,无返回值
accept的方法, 有入参,无返回值
supply的方法, 无入参,有返回值
apply的方法, 有入参,有返回值
handle的方法, 有入参,有返回值,并且带异常处理
Async结尾的方法,都是 异步的,否则是同步的。
Either结尾的方法,只需完成任意一个。
Both/Combine结尾的方法,必须所有都完成。

输出结果可能是:

也可能是:

打印结果是:

如果去掉sleep语句,那么打印的就是:

输出结果可能是:’饭做好了’,也有可能是’外卖到了’

Original: https://www.cnblogs.com/zhangzhixi/p/16624757.html
Author: Java小白的搬砖路
Title: CompletableFuture的简单使用

原创文章受到原创版权保护。转载请注明出处:https://www.johngo689.com/575250/

转载文章受原作者版权保护。转载请注明原作者出处!

(0)

大家都在看

  • [JVM] JVM的类加载机制

    JVM的类加载 首先我们来看下 Java虚拟机的类加载过程: 如上图。 当 JVM需要用到某个类的时候,虚拟机会加载它的 .class 文件。加载了相关的字节码信息之后,会常见对应…

    Java 2023年6月5日
    069
  • Convert Set to array in Java

    This post will discuss how to convert a set to an array in plain Java, Java 8, and the Gua…

    Java 2023年5月29日
    070
  • U校园自动答题和雨课堂刷视频脚本使用教程

    本篇主要参考两个github开源项目: 本篇举例的两个项目,第一个是利用 TamperMonkey 插件,第二个是直接用的.py项目 关于 TamperMonkey 可取Chrom…

    Java 2023年6月7日
    0136
  • IDEA一键部署SpringBoot项目到服务器

    1. 安装Alibaba Cloud Toolkit插件 2. 配置部署环境 2.1 为本次部署设置一个名字 2.2 选择被部署文件的生成方式 IDEA提供了三种方式: Maven…

    Java 2023年6月7日
    087
  • C# 多线程详解 Part.02(UI 线程和子线程的互动、ProgressBar 的异步调用)

    我们先来看一段运行时会抛出 InvalidOperationException 异常的代码段: 微软在子线程修改 UI 线程的控件值时给出的安全限制方案为: 在 VS2005 或者…

    Java 2023年5月29日
    088
  • (十二)springboot中shiro的使用

    一、引入maven配置 xml;toolbar:false org.apache.shiro     shiro-spring     1.4.0</p> <pr…

    Java 2023年5月29日
    071
  • 解决Watt Toolkit(原steam++)的host代理443端口被占用的问题(电脑有虚拟机进!!)

    解决Watt Toolkit(原steam++) 的host代理443端口被占用的问题 写在前面 本来没法打算更改,但是公司为了上线微软商店还是将名字改了,所以我也修改一下。 一、…

    Java 2023年6月5日
    091
  • Hystrix 断路器

    分布式系统面临的问题:复杂分布式体式结构中的应用程序有数十个依赖关系,每个依赖关系在某些时候将不可避免的失败。 多个微服务之间调用的时候,假设微服务A调用微服务B和微服务C,微服务…

    Java 2023年6月8日
    050
  • MybatisPlus拓展——实现多数据源操作

    多数据源 适用:一般工作时候会有多个数据库,每个库对应不同的业务数据。程序如果每次数据都访问同一个数据库,该数据库压力很大访问会很慢。 1、导入依赖 com.baomidou dy…

    Java 2023年6月14日
    064
  • 3.搭建SSM

    1.创建项目在Eclipse中创建项目,右键解决报错即可导入MyEclipse中,防止Myeclipse中总是报错问题2.导包(以后可能会补充) org.springframewo…

    Java 2023年6月13日
    078
  • Docker中启动Tomcat外部访问报HTTP Status 404 – 未找到

    解决办法:使用命令: docker exec -it tomcat容器ID /bin/bash 进入到tomcat的目录 Original: https://www.cnblogs…

    Java 2023年6月7日
    059
  • Redis之quicklist源码分析

    一、quicklist简介 Redis列表是简单的字符串列表,按照插入顺序排序。你可以添加一个元素到列表的头部(左边)或者尾部(右边)。 一个列表最多可以包含 232 &#8211…

    Java 2023年6月6日
    088
  • SpringMVC 使用注解时路径找不到

    SpringMVC 注解路径找不到 今天在使用SpringMVC时偶然遇到了跳转 404 的问题,于是决定记录下来 启动后输入 @RequestMapping(“/lo…

    Java 2023年6月14日
    089
  • python2的utf8编码问题

    Python中中文出现错误:SyntaxError: Non-ASCII character xxx in file x 在文件头部添加: #!/usr/bin/python -*…

    Java 2023年6月5日
    060
  • AUSTOj3

    include int i, j, k;i = 0; j = 0; k = 0;while (i < La.ength && j < Lb.length…

    Java 2023年6月15日
    070
  • ucore操作系统学习(六) ucore lab6线程调度器

    ucore在lab5中实现了较为完整的进程/线程机制,能够创建和管理位于内核态或用户态的多个线程,让不同的线程通过上下文切换并发的执行,最大化利用CPU硬件资源。ucore在lab…

    Java 2023年6月8日
    072
亲爱的 Coder【最近整理,可免费获取】👉 最新必读书单  | 👏 面试题下载  | 🌎 免费的AI知识星球