java并发编程——CompletableFuture
简介
Java的java.util.concurrent包中提供了并发相关的接口和类,本文将重点介绍CompletableFuture并发操作类
JDK1.8新增CompletableFuture该类
Class CompletableFuture<T>
java.lang.Object
java.util.concurrent.CompletableFuture<T>
All Implemented Interfaces:
CompletionStage <T>, Future <T>
可见源码中,CompletableFuture是个泛型类,意味着,肯定有地方能够传入或返回所指定的泛型类对象,在java8源码中
public class CompletableFuture<T> implements Future<T>, CompletionStage<T> {
volatile Object result; // Either the result or boxed AltResult
volatile Completion stack; // Top of Treiber stack of dependent actions
...//部分源代码省略
}
在JDK1.8的源码中,我们看见,在类定义下,最前面两个代码,定义了两个volatile的变量,我们都知道volatile变量,主要有两个作用
1.保证变量在不同线程之间的可见性,修改该变量系统会及时刷新到主内存,各线程读取的时候从主内存中读取;
2.禁止指令重排序,通过内存屏障的方式禁止指令被编译优化后的重排序。
它所实现的两个接口:Future和CompletionStage
1.Future接口

Future接口,在java多线程编程中用到很多,综合来看主要有两个方向上会用到
1.通过另外一个线程运行,并带返回值,通过future的方式传回返回值
2.程序在主线程中新建并运行新的线程后,主线程需要拿到结果,可以通过future.get阻塞的方式等待线程运行结束并拿回结果。
2.CompletionStage接口
这个主要提供异步线程任务提交、运行的管理,future主要是异步线程运行结果的管理。
综合来看CompletableFuture
1.创建任务
由于CompletableFuture中JDK8版本出来的,所以对JDK8有了非常好的支持
runAsync(Runnable)
supplyAsync(Supplier)
等等
2.获取任务结果
get()方法,获取返回值的时候,如果任务没有运行完成,则阻塞并一直等到任务结束并返回结果,而在这中间,如果持有这个completableFutre对象可以通过completableFuture.compleate(T)来手动地将结果返回get,并唤醒调用get()线程,任务线程即使运行完再返回去也接受不到了,因为已经被compleate提前返回结果了。
getNow(T vluaeIfAbsent),当调用此方法的时候,如果任务已经完成,则直接拿到返回值,如果没有则获取预设定的值,而线程运行状态不会发生改变
实例
get和getNow的区别
get阻塞代码,只到任务运行完成返回结果或者直到有人调用compleate(T)
public static void main(String[] args) {
//通过这种方式来创建一个复杂的Student并返回
CompletableFuture<Student> studentCompletableFuture = CompletableFuture.supplyAsync(() -> {
//为了模拟复杂情行
try {
Thread.sleep(5000);
} catch (InterruptedException e) {
e.printStackTrace();
}
return new Student("yan", 50);
});
//如果任务没有结束,就调用getNow的话,则返回getNow方法传入的内容
Student student = studentCompletableFuture.getNow(new Student("wang",20));
System.out.println(student.getAge());//输出20
try {
Thread.sleep(6000);
} catch (InterruptedException e) {
e.printStackTrace();
}
student = studentCompletableFuture.getNow(new Student("wang",20));
System.out.println(student.getAge());//输出50
}
get和compleate(T)使用
public static void main(String[] args) {
//通过这种方式来创建一个复杂的Student并返回
CompletableFuture<Student> studentCompletableFuture = CompletableFuture.supplyAsync(() -> {
//为了模拟复杂情行
System.out.println(Thread.currentThread().getName());
try {
Thread.sleep(5000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("我能不能运行到?");
return new Student("yan", 50);
});
ExecutorService executorService = Executors.newCachedThreadPool();
executorService.execute(() -> {
System.out.println(Thread.currentThread().getName());
try {
Thread.sleep(3000);
} catch (InterruptedException e) {
e.printStackTrace();
}
studentCompletableFuture.complete(new Student("wang", 25));
});
executorService.execute(() -> {
System.out.println(Thread.currentThread().getName());
try {
Student student = studentCompletableFuture.get();
System.out.println(student.getAge());
} catch (InterruptedException e) {
e.printStackTrace();
} catch (ExecutionException e) {
e.printStackTrace();
}
});
try {
Thread.sleep(10000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(Thread.currentThread().getName());
try {
Student student = studentCompletableFuture.get();
System.out.println(student.getAge());
} catch (InterruptedException e) {
e.printStackTrace();
} catch (ExecutionException e) {
e.printStackTrace();
}
}
执行输出结果
ForkJoinPool.commonPool-worker-1
pool-1-thread-1
pool-1-thread-2
25
我能不能运行到?
main
25
java并发编程——CompletableFuture的更多相关文章
- Java并发编程有多难?这几个核心技术你掌握了吗?
本文主要内容索引 1.Java线程 2.线程模型 3.Java线程池 4.Future(各种Future) 5.Fork/Join框架 6.volatile 7.CAS(原子操作) 8.AQS(并发同 ...
- [Java并发编程(二)] 线程池 FixedThreadPool、CachedThreadPool、ForkJoinPool?为后台任务选择合适的 Java executors
[Java并发编程(二)] 线程池 FixedThreadPool.CachedThreadPool.ForkJoinPool?为后台任务选择合适的 Java executors ... 摘要 Jav ...
- Java并发编程中的若干核心技术,向高手进阶!
来源:http://www.jianshu.com/p/5f499f8212e7 引言 本文试图从一个更高的视角来总结Java语言中的并发编程内容,希望阅读完本文之后,可以收获一些内容,至少应该知道在 ...
- Java并发编程系列-(9) JDK 8/9/10中的并发
9.1 CompletableFuture CompletableFuture是JDK 8中引入的工具类,实现了Future接口,对以往的FutureTask的功能进行了增强. 手动设置完成状态 Co ...
- Java并发编程--基础进阶高级(完结)
Java并发编程--基础进阶高级完整笔记. 这都不知道是第几次刷狂神的JUC并发编程了,从第一次的迷茫到现在比较清晰,算是个大进步了,之前JUC笔记不见了,重新做一套笔记. 参考链接:https:// ...
- 【Java并发编程实战】----- AQS(四):CLH同步队列
在[Java并发编程实战]-–"J.U.C":CLH队列锁提过,AQS里面的CLH队列是CLH同步锁的一种变形.其主要从两方面进行了改造:节点的结构与节点等待机制.在结构上引入了头 ...
- 【Java并发编程实战】----- AQS(三):阻塞、唤醒:LockSupport
在上篇博客([Java并发编程实战]----- AQS(二):获取锁.释放锁)中提到,当一个线程加入到CLH队列中时,如果不是头节点是需要判断该节点是否需要挂起:在释放锁后,需要唤醒该线程的继任节点 ...
- 【Java并发编程实战】----- AQS(二):获取锁、释放锁
上篇博客稍微介绍了一下AQS,下面我们来关注下AQS的所获取和锁释放. AQS锁获取 AQS包含如下几个方法: acquire(int arg):以独占模式获取对象,忽略中断. acquireInte ...
- 【Java并发编程实战】-----“J.U.C”:CLH队列锁
在前面介绍的几篇博客中总是提到CLH队列,在AQS中CLH队列是维护一组线程的严格按照FIFO的队列.他能够确保无饥饿,严格的先来先服务的公平性.下图是CLH队列节点的示意图: 在CLH队列的节点QN ...
- 【Java并发编程实战】-----“J.U.C”:CountDownlatch
上篇博文([Java并发编程实战]-----"J.U.C":CyclicBarrier)LZ介绍了CyclicBarrier.CyclicBarrier所描述的是"允许一 ...
随机推荐
- 使用 Databricks 进行营销效果归因分析的应用实践【Databricks 数据洞察公开课】
简介: 本文介绍如何使用Databricks进行广告效果归因分析,完成一站式的部署机器学习,包括数据ETL.数据校验.模型训练/评测/应用等全流程. 作者:冯加亮 阿里云开源大数据平台技术工程师 ...
- Flink SQL 1.11 on Zeppelin 平台化实践
简介: 鉴于有很多企业都无法配备专门的团队来解决 Flink SQL 平台化的问题,那么到底有没有一个开源的.开箱即用的.功能相对完善的组件呢?答案就是本文的主角--Apache Zeppelin. ...
- 干掉讨厌的 CPU 限流,让容器跑得更快
简介: 让人讨厌的 CPU 限流影响容器运行,有时人们不得不牺牲容器部署密度来避免 CPU 限流出现.本文介绍的 CPU Burst 技术可以帮助您既能保证容器运行服务质量,又不降低容器部署密度.文 ...
- WPF 对接 Vortice 调用 WIC 加载图片
本文将告诉大家如何通过 Vortice 库从底层的方式使用 WIC 层加载本地图片文件,解码为 IWICBitmap 图片,然后将 IWICBitmap 图片交给 WPF 进行渲染 本文的前置博客:W ...
- Raft 共识算法1-Raft基础
Raft 共识算法1-Raft基础 Raft算法中译版地址:http://www.redisant.cn/etcd/contact 英原论文地址:https://raft.github.io/raft ...
- OLAP系列之分析型数据库clickhouse权限控制(六)
一.clickhouse权限管理 users.xml默认配置文件: <?xml version="1.0"?> <clickhouse> <profi ...
- SpringBoot注入时设置《多例》
SpringBoot设置多例 1.准备数据 测试接口 package com.cc.jschdemo.springmultiton; /** * <p>spring多例测试</p&g ...
- 微服务 - 作业调度 · Hangfire集成式 · 仪表盘 · DolphinScheduler分布式 · 定义流程
系列目录 微服务 - 1.概念 · 应用 · 架构 · 通讯 · 授权 · 跨域 · 限流 微服务 - 2.IdentityServer4认证授权 · 概念认识 · 运行过程 · 实践应用 微服务 - ...
- shell 去掉逗号_shell替换和去掉换行符
用shell处理文件的时候我们常常需要去掉或者加上换行符,name问题就来了怎么才能快速的替换呢? 我们有这样一个文件[root@hxy working]# cat 1 GD200A16C013493 ...
- three.js教程1补充-gui.js库使用
gui.js是一个前端js库,对HTML.CSS和JavaScript进行了封装,学习开发的时候,借助dat.gui.js可以快速创建可手动控制三维场景的UI交互界面,打开API文档中案例体验一下就能 ...