创建 CompletableFuture 对象实例我们可以使用如下几个方法:

static CompletableFuture<U> completedFuture(U value)//使用forkjoin公共线程池
static CompletableFuture<Void> runAsync(Runnable runnable)
static CompletableFuture<U> supplyAsync(Supplier<U> supplier)//使用自定义线程池
static CompletableFuture<Void> runAsync(Runnable runnable, Executor executor)
static CompletableFuture<U> supplyAsync(Supplier<U> supplier, Executor executor)

第一个方法创建一个具有默认结果的 CompletableFuture,这个没啥好讲。我们重点讲述下下面四个异步方法。

前两个方法 runAsync 不支持返回值,而 supplyAsync可以支持返回结果。

这个两个方法默认将会使用公共的 ForkJoinPool 线程池执行,这个线程池默认线程数是 CPU 的核数。

可以设置 JVM option:-Djava.util.concurrent.ForkJoinPool.common.parallelism 来设置 ForkJoinPool 线程池的线程数

使用共享线程池将会有个弊端,一旦有任务被阻塞,将会造成其他任务没机会执行。所以强烈建议使用后两个方法,根据任务类型不同,主动创建线程池,进行资源隔离,避免互相干扰。

-------------------------------------------------------

CompletableFuture的创建:

  • 说明:

    • 两个重载方法之间的区别 => 后者可以传入自定义Executor,前者是默认的,使用的ForkJoinPool

    • supplyAsync和runAsync方法之间的区别 => 前者有返回值,后者无返回值

    • Supplier是函数式接口,因此该方法需要传入该接口的实现类,追踪源码会发现在run方法中会调用该接口的方法。因此使用该方法创建CompletableFuture对象只需重写Supplier中的get方法,在get方法中定义任务即可。又因为函数式接口可以使用Lambda表达式,和new创建CompletableFuture对象相比代码会简洁不少

    • 使用new方法

CompletableFuture<Double> futurePrice = new CompletableFuture<>();

使用CompletableFuture#completedFuture静态方法创建

public static <U> CompletableFuture<U> completedFuture(U value) {return new CompletableFuture<U>((value == null) ? NIL : value);
}
  • 参数的值为任务执行完的结果,一般该方法在实际应用中较少应用

  • 使用 CompletableFuture#supplyAsync静态方法创建 supplyAsync有两个重载方法:


//方法一
public static <U> CompletableFuture<U> supplyAsync(Supplier<U> supplier) {return asyncSupplyStage(asyncPool, supplier);
}
//方法二
public static <U> CompletableFuture<U> supplyAsync(Supplier<U> supplier,Executor executor) {return asyncSupplyStage(screenExecutor(executor), supplier);
}
  • 使用CompletableFuture#runAsync静态方法创建 runAsync有两个重载方法

//方法一
public static CompletableFuture<Void> runAsync(Runnable runnable) {return asyncRunStage(asyncPool, runnable);
}
//方法二
public static CompletableFuture<Void> runAsync(Runnable runnable, Executor executor) {return asyncRunStage(screenExecutor(executor), runnable);
}

结果的获取: 对于结果的获取CompltableFuture类提供了四种方式

//方式一
public T get()
//方式二
public T get(long timeout, TimeUnit unit)
//方式三
public T getNow(T valueIfAbsent)
//方式四
public T join()
  • 说明:

    示例:

    • get()和get(long timeout, TimeUnit unit) => 在Future中就已经提供了,后者提供超时处理,如果在指定时间内未获取结果将抛出超时异常

    • getNow => 立即获取结果不阻塞,结果计算已完成将返回结果或计算过程中的异常,如果未计算完成将返回设定的valueIfAbsent值

    • join => 方法里不会抛出异常

public class AcquireResultTest {public static void main(String[] args) throws ExecutionException, InterruptedException {//getNow方法测试CompletableFuture<String> cp1 = CompletableFuture.supplyAsync(() -> {try {Thread.sleep(60 * 1000 * 60 );} catch (InterruptedException e) {e.printStackTrace();}return "hello world";});System.out.println(cp1.getNow("hello h2t"));//join方法测试CompletableFuture<Integer> cp2 = CompletableFuture.supplyAsync((()-> 1 / 0));System.out.println(cp2.join());//get方法测试CompletableFuture<Integer> cp3 = CompletableFuture.supplyAsync((()-> 1 / 0));System.out.println(cp3.get());}
}

说明:

  • 第一个执行结果为hello h2t,因为要先睡上1分钟结果不能立即获取

  • join方法获取结果方法里不会抛异常,但是执行结果会抛异常,抛出的异常为CompletionException

  • get方法获取结果方法里将抛出异常,执行结果抛出的异常为ExecutionException

  • 异常处理: 使用静态方法创建的CompletableFuture对象无需显示处理异常,使用new创建的对象需要调用completeExceptionally方法设置捕获到的异常,举例说明:

CompletableFuture completableFuture = new CompletableFuture();
new Thread(() -> {try {//doSomething,调用complete方法将其他方法的执行结果记录在completableFuture对象中completableFuture.complete(null);} catch (Exception e) {//异常处理completableFuture.completeExceptionally(e);}
}).start();

CompletableFuture详解~创建实例相关推荐

  1. python中递归函数的实例_Python 递归函数详解及实例

    Python 递归函数 如果一个函数体直接或者间接调用自己,那么这个函数就称为递归函数.也就是说,递归函数体的执行过程中可能会返回去再次调用该函数.在python里,递归函数不需要任何特殊的语法,但是 ...

  2. java拉姆达表达式事例,Java Lambda表达式详解和实例

    简介 Lambda表达式是Java SE 8中一个重要的新特性.lambda表达式允许你通过表达式来代替功能接口. lambda表达式就和方法一样,它提供了一个正常的参数列表和一个使用这些参数的主体( ...

  3. C++ 中的this指针详解及实例

    C++ 中的this指针详解及实例 这篇文章主要介绍了C++ 中的this指针详解及实例的相关资料,this指针是类的一个自动生成.自动隐蔽的私有成员,它存在于类的非静态成员中,指向被调用函数所在的对 ...

  4. Java 线程池详解及实例代码

    转载自  Java 线程池详解及实例代码 这篇文章主要介绍了Java 线程池的相关资料,并符实例代码,帮助大家学习参考,需要的朋友可以参考下 线程池的技术背景 在面向对象编程中,创建和销毁对象是很费时 ...

  5. java list用法_Java List 用法详解及实例分析

    Java List 用法详解及实例分析 Java中可变数组的原理就是不断的创建新的数组,将原数组加到新的数组中,下文对Java List用法做了详解. List:元素是有序的(怎么存的就怎么取出来,顺 ...

  6. angular 注入器配置_Angular2 多级注入器详解及实例

    angular2 的依赖注入包含了太多的内容,其中的一个重点就是注入器,而注入器又非常难理解,今天我们不深入介绍注入器的内容,可以参考官方文档,我们今天来说注入器的层级. 也就是组件获取服务的容器会选 ...

  7. 红帽Linux故障定位技术详解与实例(3)

    红帽Linux故障定位技术详解与实例(3) 在线故障定位就是在故障发生时, 故障所处的操作系统环境仍然可以访问,故障处理人员可通过console, ssh等方式登录到操作系统上,在shell上执行各种 ...

  8. linux 解压所有以zip结尾的文件_Linux下的压缩zip,解压缩unzip命令详解及实例

    摘自:https://www.cnblogs.com/yves0923/p/10965021.html Linux下的压缩解压缩命令详解及实例 实例:压缩服务器上当前目录的内容为xxx.zip文件 z ...

  9. CvMat、Mat、IplImage之间的转换详解及实例

    IplImage: 在OpenCV中IplImage是表示一个图像的结构体,也是从OpenCV1.0到目前最为重要的一个结构: 在之前的图像表示用IplImage,而且之前的OpenCV是用C语言编写 ...

最新文章

  1. ORACLE 中极易混淆的几个 NAME 的分析和总结
  2. centos6.5环境wget报错Unable to establish SSL connection
  3. CSS3实战开发:使用CSS3实现photoshop的过滤效果
  4. HNOI2019fish
  5. dc综合与pt静态时序分析(中文)_小三电系统(PDU+DC+OBC)的技术研究
  6. [vue] vue变量名如果以_、$开头的属性会发生什么问题?怎么访问到它们的值?
  7. bzoj 4319: cerc2008 Suffix reconstruction(构造)
  8. [JDK8] Lambda
  9. Linux内核多线程(四)
  10. oracle jdk下载镜像
  11. Windows和Linux拷贝文件的方法
  12. 中维监控显示无法连接服务器失败,中维远程监控系统服务器端
  13. WebGame服务端架构分析(一)
  14. 在线 服务器 web,web服务器是什么?
  15. 1. spark ML概述
  16. 最新最全论文合集——纵向联邦学习
  17. 如何做好运营?运营类产品经理必须知道的几个常用功能设计方案
  18. 使用内部RC的导致串口通讯错误率高甚至失败的原因及解决办法
  19. 抖音快手短视频批量去水印采集软件v1.8使用文档
  20. Hold Time违例,该如何解决

热门文章

  1. Spring Cloud实战小贴士:Zuul统一异常处理(一)
  2. 会议交流 | 最新NLP核心技术与前沿实践分享!
  3. 论文浅尝 | 机器阅读理解中常识知识的显式利用
  4. 关系抽取、时间抽取,实践项目推荐
  5. Python:Tensorflow中两个稀疏张量相乘
  6. 阿里云数据库Mysql被黑
  7. 推荐几个练习听力不错的国外网站
  8. 2018-2019-2 网络对抗技术 20165301 Exp2 后门原理与实践
  9. Windows中使用wget整站下载
  10. CJOJ 1087 【NOIP2010】乌龟棋 / Luogu 1541 乌龟棋(动态规划)