Java 8 CompletableFuture思考

最近一直在用响应式编程写Java代码,用的框架大概上有WebFlux(Spring)、R2dbcAkka...一些响应式的框架。

全都是Java写的,我于是就在想:

全都是Java的代码怎么搞成了响应式呢? 是不是语言本身就支持呢?

于是找到了Java 8 的 concurrency。这个是啥呢?

写个代码看一下:

@Test
void test7() throws ExecutionException, InterruptedException {
CompletableFuture<String> future = new CompletableFuture<>();
Runnable task = new Runnable() {
@Override
public void run() {
try {
String result = "result";
future.complete(result);
} catch (Exception e) {
future.completeExceptionally(e);
}
}
};
//这里是new了一个新的线程去跑
final Thread thread = new Thread(task);
thread.start();
final String s = future.get();
assertEquals("result", s);
}

代码写到了这里,感觉和JS的Promise如出一辙呀:

it('just a promise test', function () {
Promise.resolve('success'); // return promise
Promise.reject('error'); // return promise
new Promise((resolve, reject) => {
resolve('success');
reject('error');
});
});

ForkJoinPool玩一把

@Test
void test8() throws ExecutionException, InterruptedException {
CompletableFuture<String> future = new CompletableFuture<>();
final Runnable runnable = () -> {
try {
String result = "result";
future.complete(result);
} catch (Exception e) {
future.completeExceptionally(e);
}
}; ForkJoinPool forkJoinPool = ForkJoinPool.commonPool();
forkJoinPool.submit(runnable);
final String s = future.get();
assertEquals("result", s);
}

写到了这里,我感觉我大概明白了所用的响应式框架里边怎么玩的了。


假设说不用框架纯Java的代码怎么写那些响应式代码呢?

比如说常用的操作符map,zip,reduce,group...这些要怎么玩?

@Test
void test9() throws ExecutionException, InterruptedException, TimeoutException {
CompletableFuture<String> future = new CompletableFuture<>();
final Runnable runnable1 = () -> {
try {
String result = "1";
future.complete(result);
} catch (Exception e) {
future.completeExceptionally(e);
}
}; CompletableFuture<String> future2 = new CompletableFuture<>();
final Runnable runnable2 = () -> {
try {
String result = "2";
future2.complete(result);
} catch (Exception e) {
future2.completeExceptionally(e);
}
}; ForkJoinPool forkJoinPool = ForkJoinPool.commonPool();
forkJoinPool.submit(runnable1);
forkJoinPool.submit(runnable2);
final List<Integer> result = future
.whenComplete((aVoid, throwable) -> {
if (Objects.nonNull(throwable)) {
log.error("bla bla bla,", throwable);
} })
.thenApply(s -> Integer.parseInt(s)) // like stream Map
.thenCombine(future2, (integer, s) -> Arrays.asList(integer, Integer.parseInt(s)))// zip
.thenCompose(list -> CompletableFuture.completedFuture(list)) // flatMap or mapAsync
.get(3, TimeUnit.SECONDS);
assertThat(result)
.containsExactly(1, 2);
}

这些.thenXXX方法都是可以换成.thenXXXAsync的,之间的不同就是换成另一个线程去处理,而不是当前线程继续处理。

如何做reduce,collect,groupBy,orderBy操作呢?

答案:.thenComposeor.thenApply方法

@Test
void test10() throws ExecutionException, InterruptedException, TimeoutException {
CompletableFuture<List<Integer>> future = new CompletableFuture<>();
final Runnable runnable1 = () -> {
try {
future.complete(Arrays.asList(1, 3, 5));
} catch (Exception e) {
future.completeExceptionally(e);
}
};
ForkJoinPool forkJoinPool = ForkJoinPool.commonPool();
forkJoinPool.submit(runnable1);
final Integer result = future
.thenCompose(list -> CompletableFuture.completedFuture(list.stream().reduce(0, Integer::sum)))
.get(3, TimeUnit.SECONDS);
assertThat(result).isEqualTo(3);
}

有没有类似于Promise.all和Promise.race之类的方法呢?

答案是有的CompletableFuture.allOf(futures...)CompletableFuture.anyOf(futures...)

总结

断断续续思考了两天,心中的困惑才一点点的解开,有深度的思考是不可缺少的。

source

https://github.com/1483523635/blogs/blob/master/java/basic/future.md

Java 8 CompletableFuture思考的更多相关文章

  1. 关于Java 项目的思考总结

    Java 项目思考总结 前言 今天是2017年3月25日,笔者已经毕业半年,工作经验一年. 正好有心思写这个总结. 持续开发 对于Java项目,我所接触的一般就是JavaWeb项目和 Java Jar ...

  2. Java异步CompletableFuture的使用

    所谓异步调用其实就是实现一个可无需等待被调用函数的返回值而让操作继续运行的方法.Java中的CompletableFuture 提供了四个静态方法来创建一个异步操作. public static Co ...

  3. Java框架的思考

    目前的JAVA 企业级开发框架,我们常用的大致包括IOC AOP MVC ORM框架 1. IOC spring是一个非常棒的ico容器,其思想非常简单,用一个集合对象如MAP 来缓存对象(对象都是单 ...

  4. 关于java对象的思考

    不可变对象和类 由不可变类创建的对象就是不可变对象,要使一个类成为不可变的,它必须满足下面的需求: 所有数据域都是私有的 没有修改器方法 没有一个访问器的方法,它会返回一个指向可变数据域的引用 看下面 ...

  5. 对 Kotlin 与 Java 编程语言的思考

    从长远来看,排名前10的也基本上是Java.C.C++.Python.C#.VB.PHP.JavaScript.至于Kotlin的排名,11月份在编程语言仅排41名,Ratings仅有0.216%. ...

  6. 有 a - b < c 对Java安全性的思考

    软件工程中,不论使用哪种开发语言,安全性一直是一个非常棘手却又重要的问题.安全性是软件开发领域永远的主题之一,而且随着互联网的蜂拥发展而带动的新技术的兴起与革命(比如近几年火起来的node.js,py ...

  7. 【多线程】java多线程Completablefuture 详解【在spring cloud微服务之间调用,防止接口超时的应用】【未完成】

    参考地址:https://www.jianshu.com/p/6f3ee90ab7d3 示例: public static void main(String[] args) throws Interr ...

  8. 关于Java协变性的思考

    简而言之,如果A IS-A B,那么A[] IS-A B[]. 举例:现在有类型Person.Employee和Student.Employee 是一个(IS-A) Person,Student是一个 ...

  9. 关于java异常处理的思考

    学习java的过程中,初学者更多的是为了实验而写代码,而不考虑实际情况中的人机交互过程中的一些问题. 在java项目中,更多的用户不会因为你给了某些限制提醒,他就一定会按照你所给的提示来输入或者操作, ...

随机推荐

  1. 通过bat文件 进行mysql 连接 或者 操作涉及 密码的,如果密码 中有 % 号的话要特殊处理

    比如我想在bat文件中进行一个数据库的连接 或者进行一个数据库中的 数据 导入或者导出(mysqldump) 这样子都会用到数据库密码, 假如这个数据库的密码 中又有 % 的话就要特殊转义一下才行执行 ...

  2. 用Python介绍了企业资产情况的数据爬取、分析与展示。

    前言 文的文字及图片来源于网络,仅供学习.交流使用,不具有任何商业用途,版权归原作者所有,如有问题请及时联系我们以作处理. 作者:张耀杰 PS:如有需要Python学习资料的小伙伴可以加点击下方链接自 ...

  3. ASE课程总结 by 冯晓云

    开始的开始,采访往届ASE班的blog:http://www.cnblogs.com/legs/p/4894362.html 和北航软工M1检查:http://www.cnblogs.com/legs ...

  4. weblogic漏洞(一)----CVE-2017-10271

    WebLogic XMLDecoder反序列化漏洞(CVE-2017-10271) 0x01 漏洞原因: Weblogic的WLS Security组件对外提供webservice服务,其中使用了XM ...

  5. [PHP] 获取IP 和JS获取IP和地址

    通过js获取 服务器 ip 服务器端口 服务器地址 var address=window.location.href; thisDLoc = document.location; var hostpo ...

  6. react: typescript system params optimize

    1.system-params-service import paramCache from "../common/param-cache" import RequestPromi ...

  7. Serlvet容器与Web应用

    对启动顺序的错误认识 之前一直有个观点,应用运行在Servlet容器中,因为从Servlet容器与Web应用的使用方式来看,确实很有这种感觉. 我们每次都是启动Servlet容器,然后再启动我们的应用 ...

  8. tp5--模型关联

    来源于:https://blog.csdn.net/u012600104/article/details/78927629 先说明,模型关联和join管理是不一样的,用文章和评论的关系来举例.(一对多 ...

  9. [Inno Setup] 在 File Section 之前解压文件

    Prototype: procedure ExtractTemporaryFile(const FileName: String); Description: Extracts the specifi ...

  10. [Qt] 打开文件夹 Windows

    bool ok = QDesktopServices::openUrl(QUrl("c:/users/administrator/desktop/dir"));