CompletableFuture详解~创建实例
创建 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详解~创建实例相关推荐
- python中递归函数的实例_Python 递归函数详解及实例
Python 递归函数 如果一个函数体直接或者间接调用自己,那么这个函数就称为递归函数.也就是说,递归函数体的执行过程中可能会返回去再次调用该函数.在python里,递归函数不需要任何特殊的语法,但是 ...
- java拉姆达表达式事例,Java Lambda表达式详解和实例
简介 Lambda表达式是Java SE 8中一个重要的新特性.lambda表达式允许你通过表达式来代替功能接口. lambda表达式就和方法一样,它提供了一个正常的参数列表和一个使用这些参数的主体( ...
- C++ 中的this指针详解及实例
C++ 中的this指针详解及实例 这篇文章主要介绍了C++ 中的this指针详解及实例的相关资料,this指针是类的一个自动生成.自动隐蔽的私有成员,它存在于类的非静态成员中,指向被调用函数所在的对 ...
- Java 线程池详解及实例代码
转载自 Java 线程池详解及实例代码 这篇文章主要介绍了Java 线程池的相关资料,并符实例代码,帮助大家学习参考,需要的朋友可以参考下 线程池的技术背景 在面向对象编程中,创建和销毁对象是很费时 ...
- java list用法_Java List 用法详解及实例分析
Java List 用法详解及实例分析 Java中可变数组的原理就是不断的创建新的数组,将原数组加到新的数组中,下文对Java List用法做了详解. List:元素是有序的(怎么存的就怎么取出来,顺 ...
- angular 注入器配置_Angular2 多级注入器详解及实例
angular2 的依赖注入包含了太多的内容,其中的一个重点就是注入器,而注入器又非常难理解,今天我们不深入介绍注入器的内容,可以参考官方文档,我们今天来说注入器的层级. 也就是组件获取服务的容器会选 ...
- 红帽Linux故障定位技术详解与实例(3)
红帽Linux故障定位技术详解与实例(3) 在线故障定位就是在故障发生时, 故障所处的操作系统环境仍然可以访问,故障处理人员可通过console, ssh等方式登录到操作系统上,在shell上执行各种 ...
- linux 解压所有以zip结尾的文件_Linux下的压缩zip,解压缩unzip命令详解及实例
摘自:https://www.cnblogs.com/yves0923/p/10965021.html Linux下的压缩解压缩命令详解及实例 实例:压缩服务器上当前目录的内容为xxx.zip文件 z ...
- CvMat、Mat、IplImage之间的转换详解及实例
IplImage: 在OpenCV中IplImage是表示一个图像的结构体,也是从OpenCV1.0到目前最为重要的一个结构: 在之前的图像表示用IplImage,而且之前的OpenCV是用C语言编写 ...
最新文章
- ORACLE 中极易混淆的几个 NAME 的分析和总结
- centos6.5环境wget报错Unable to establish SSL connection
- CSS3实战开发:使用CSS3实现photoshop的过滤效果
- HNOI2019fish
- dc综合与pt静态时序分析(中文)_小三电系统(PDU+DC+OBC)的技术研究
- [vue] vue变量名如果以_、$开头的属性会发生什么问题?怎么访问到它们的值?
- bzoj 4319: cerc2008 Suffix reconstruction(构造)
- [JDK8] Lambda
- Linux内核多线程(四)
- oracle jdk下载镜像
- Windows和Linux拷贝文件的方法
- 中维监控显示无法连接服务器失败,中维远程监控系统服务器端
- WebGame服务端架构分析(一)
- 在线 服务器 web,web服务器是什么?
- 1. spark ML概述
- 最新最全论文合集——纵向联邦学习
- 如何做好运营?运营类产品经理必须知道的几个常用功能设计方案
- 使用内部RC的导致串口通讯错误率高甚至失败的原因及解决办法
- 抖音快手短视频批量去水印采集软件v1.8使用文档
- Hold Time违例,该如何解决