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. 《SQL 反模式》 学习笔记

    第一章 引言 GoF 所著的的<设计模式>,在软件领域引入了"设计模式"(design pattern)的概念. 而后,Andrew Koenig 在 1995 年造了 ...

  2. Laravel 上手增删改查

    拿到一个框架,除了解框架,还要能实现基本的CURD操作. 添加 1.配置路由,指定添加页面: // routes/web.php 中增加如下: // 添加页面.存放路径 Laravel7/resour ...

  3. 初识Cobalt Strike

    简介 Cobalt Strike 一款以metasploit为基础的GUI的框架式渗透工具,集成了端口转发.服务扫描,自动化溢出,多模式端口监听,win exe木马生成,win dll木马生成,jav ...

  4. [转+自]disable_functions之巧用LD_PRELOAD突破

    写在前面: 通过知乎的一篇艰难的渗透提权,引发了一些对于disable_funcionts绕过的思考,虽然在暑假日记中记载了四种绕过disable_functions,比如com组件,pcntl_ex ...

  5. 吃瓜的正确姿势,Python绘制罗志祥词云图

    前言 文的文字及图片来源于网络,仅供学习.交流使用,不具有任何商业用途,版权归原作者所有,如有问题请及时联系我们以作处理. 这篇文章中向大家介绍了Python绘制词云的方法,不难看出绘制词云可以说是一 ...

  6. Netty入门与实战教程总结分享

    前言:都说Netty是Java程序员必须要掌握的一项技能,带着不止要知其然还要知其所以然的目的,在慕课上找了一个学习Netty源码的教程,看了几章后着实有点懵逼.虽然用过Netty,并且在自己的个人网 ...

  7. python信息收集(三)

        前两篇介绍了利用python编写一些脚本实现二层主机的发现,这一篇介绍一下三层主机的发现.     一般来说,三层主机的发现主要是通过ICMP协议来实现的.其中ICMP协议中的ping命令可以 ...

  8. Linux下jdk的安装和环境变量的配置

    Linux下jdk的安装和环境变量的配置 一.jdk的下载 方式一:在官网下载 http://www.oracle.com/technetwork/java/javase/downloads/inde ...

  9. thinkphp5 csv格式导入导出(多数据处理)

    关于csv文件格式的导出导入个人见解 先上代码: <?php namespace think; class Csv { /** * 导出csv文件 * @param $list 数据源 * @p ...

  10. 2019.11.13课堂实验之用Linux下的shell脚本完成两文本交替输出

    有两个文本如下,实际中并不知道两文本各有多少行: 文本1.txt aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa ccccccccccccccccccccccccccc ...