flux java_Java反应式框架Reactor中的Mono和Flux

bdf164d44944

1. 前言

最近写关于响应式编程的东西有点多,很多同学反映对Flux和Mono这两个Reactor中的概念有点懵逼。但是目前Java响应式编程中我们对这两个对象的接触又最多,诸如Spring WebFlux、RSocket、R2DBC。我开始也对这两个对象头疼,所以今天我们就简单来探讨一下它们。

2. 响应流的特点

要搞清楚这两个概念,必须说一下响应流规范。它是响应式编程的基石。他具有以下特点:

响应流必须是无阻塞的。

响应流必须是一个数据流。

它必须可以异步执行。

并且它也应该能够处理背压。

背压是反应流中的一个重要概念,可以理解为,生产者可以感受到消费者反馈的消费压力,并根据压力进行动态调整生产速率。形象点可以按照下面理解:

bdf164d44944

有没有背压的两种情形

3. Publisher

由于响应流的特点,我们不能再返回一个简单的POJO对象来表示结果了。必须返回一个类似Java中的Future的概念,在有结果可用时通知消费者进行消费响应。

Reactive Stream规范中这种被定义为Publisher ,Publisher是一个可以提供0-N个序列元素的提供者,并根据其订阅者Subscriber super T>的需求推送元素。一个Publisher可以支持多个订阅者,并可以根据订阅者的逻辑进行推送序列元素。下面这个Excel计算就能说明一些Publisher的特点。

bdf164d44944

A1-A9就可以看做Publisher及其提供的元素序列。A10-A13分别是求和函数SUM(A1:A9)、平均函数AVERAGE(A1:A9)、最大值函数MAX(A1:A9)、最小值函数MIN(A1:A9),可以看作订阅者Subscriber。假如说我们没有A10-A13,那么A1-A9就没有实际意义,它们并不产生计算。这也是响应式的一个重要特点:当没有订阅时发布者什么也不做。

而Flux和Mono都是Publisher在Reactor 3实现。Publisher提供了subscribe方法,允许消费者在有结果可用时进行消费。如果没有消费者Publisher不会做任何事情,他根据消费情况进行响应。 Publisher可能返回零或者多个,甚至可能是无限的,为了更加清晰表示期待的结果就引入了两个实现模型Mono和Flux。

4. Flux

Flux 是一个发出(emit)0-N个元素组成的异步序列的Publisher,可以被onComplete信号或者onError信号所终止。在响应流规范中存在三种给下游消费者调用的方法 onNext, onComplete, 和onError。下面这张图表示了Flux的抽象模型:

bdf164d44944

Flux

以上的的讲解对于初次接触反应式编程的依然是难以理解的,所以这里有一个循序渐进的理解过程。

有些类比并不是很妥当,但是对于你循序渐进的理解这些新概念还是有帮助的。

传统数据处理

我们在平常是这么写的:

public List allUsers() {

return Arrays.asList(new ClientUser("felord.cn", "reactive"),

new ClientUser("Felordcn", "Reactor"));

}

我们通过迭代返回值List来get这些元素进行再处理(消费),这种方式有点类似厨师做了很多菜,吃不吃在于食客。需要食客主动去来吃就行了(pull的方式),至于喜欢吃什么不喜欢吃什么自己随意,怎么吃也自己随意。

流式数据处理

在Java 8中我们可以改写为流的表示:

public Stream allUsers() {

return Stream.of(new ClientUser("felord.cn", "reactive"),

new ClientUser("Felordcn", "Reactor"));

}

依然是厨师做了很多菜,但是这种就更加高级了一些,提供了菜品的搭配方式(不包含具体细节),食客可以按照说明根据自己的习惯搭配着去吃,一但开始概不退换,吃完为止,过期不候。

反应式数据处理

在Reactor中我们又可以改写为Flux表示:

public Flux allUsers(){

return Flux.just(new ClientUser("felord.cn", "reactive"),

new ClientUser("Felordcn", "Reactor"));

}

这时候食客只需要订餐就行了,做好了自然就呈上来,而且可以随时根据食客的饭量进行调整。如果没有食客订餐那么厨师就什么都不用做。当然不止有这么点特性,不过对于方便我们理解来说这就够了。

5. Mono

Mono 是一个发出(emit)0-1个元素的Publisher,可以被onComplete信号或者onError信号所终止。

bdf164d44944

Mono

这里就不翻译了,整体和Flux差不多,只不过这里只会发出0-1个元素。也就是说不是有就是没有。象Flux一样,我们来看看Mono的演化过程以帮助理解。

传统数据处理

public ClientUser currentUser () {

return isAuthenticated ? new ClientUser("felord.cn", "reactive") : null;

}

直接返回符合条件的对象或者null。

Optional的处理方式

public Optional currentUser () {

return isAuthenticated ? Optional.of(new ClientUser("felord.cn", "reactive"))

: Optional.empty();

}

这个Optional我觉得就有反应式的那种味儿了,当然它并不是反应式。当我们不从返回值Optional取其中具体的对象时,我们不清楚里面到底有没有,但是Optional是一定客观存在的,不会出现NPE问题。

反应式数据处理

public Mono currentUser () {

return isAuthenticated ? Mono.just(new ClientUser("felord.cn", "reactive"))

: Mono.empty();

}

和Optional有点类似的机制,当然Mono不是为了解决NPE问题的,它是为了处理响应流中单个值(也可能是Void)而存在的。

6. 总结

Flux和Mono是Java反应式中的重要概念,但是很多同学包括我在开始都难以理解它们。这其实是规定了两种流式范式,这种范式让数据具有一些新的特性,比如基于发布订阅的事件驱动,异步流、背压等等。另外数据是推送(Push)给消费者的以区别于平时我们的拉(Pull)模式。同时我们可以像Stream Api一样使用类似map、flatmap等操作符(operator)来操作它们。对Flux和Mono这两个概念需要花一些时间去理解它们,不能操之过急。如果你对我的这种看法有不同的观点可以留言讨论,多多关注:码农小胖哥 获取更多干货知识。

关注公众号:码农小胖哥,获取更多资讯

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/540015.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

MySQL grant 权限,分别可以作用在多个层次上

1. grant 作用在整个 MySQL 服务器上:grant select on *.* to dbalocalhost; -- dba 可以查询 MySQL 中所有数据库中的表。grant all on *.* to dbalocalhost; -- dba 可以管理 MySQL 中的所有数据库2. grant 作用在单个数据库上:grant select on testdb…

用了2年的EOS的感受

EOS是普元信息技术股份有限公司开发的产品,核心是eclipse,给eclipse穿上了很多衣服。不知道普元公司给eclipse捐款了没。 开发人员可以从它的官网免费下载,免费用。免费版的服务器最多链接数是5个人,这5个人在生产上行不通的&…

java 线程分组_Java多线程可以分组,还能这样玩!

前面的文章,栈长和大家分享过多线程创建的3种方式《实现 Java 多线程的 3 种方式》。但如果线程很多的情况下,你知道如何对它们进行分组吗?和 Dubbo 的服务分组一样,Java 可以对相同性质的线程进行分组。来看下线程类 Thread 的所…

关于Android构建

“IDE都是给小白程序员的,大牛级别的程序员一定是命令行控,终端控,你看大牛都是使用vim,emacs 就一切搞定” 这话说的虽然有些绝对,但是也不无道理,做开发这行要想效率高,自动化还真是缺少不了命令行工具&a…

普元EOS开发学习(二)

1、QueryFormQueryForm控件是一个用来输入查询条件的表单&#xff0c;作为一个代码片断&#xff0c;以<h:form></h:form>形式嵌入在JSP页面中。表单提交时&#xff0c;根据控件生成时设置的逻辑&#xff0c;可以对指定数据集进行有条件查询&#xff0c;同时可以根据…

java map class_Java:声明一个包含两个相关泛型类型的Map(Map,Class ?extends ClassB )...

另一种方法是提供自己的Map实现.如果扩展现有实现并使用新类型,则不需要太多代码&#xff1a;public class CompatibleHashMap extends HashMap, ClassB> {}现在,一个CompatibleHashMap< String>只允许你把ClassA< String>作为键和ClassB< String>作为价值…

centos 6 安装zabbix 3.0

1.安装PHP Zabbix 3.0对PHP的要求最低为5.4&#xff0c;而CentOS6默认为5.3.3&#xff0c;完全不满足要求&#xff0c;故需要利用第三方源&#xff0c;将PHP升级到5.4以上&#xff0c;注意&#xff0c;不支持PHP7 rpm -ivh http://repo.webtatic.com/yum/el6/latest.rpm yum in…

普元EOS开发学习(一)

警惕EOS的拖图元开发导致技术退步&#xff0c;请阅博主《用了2年EOS后的感受》 --------------- EOS开发和原有的JAVA开发有很大的不同&#xff0c;在开发的过程中&#xff0c;只能看到JSP页面的源代码&#xff0c;如果想要了解到操作类型的代码&#xff0c;那么你只能看到XML…

java 共享锁 独占锁_java中的公平锁、非公平锁、可重入锁、递归锁、自旋锁、独占锁和共享锁...

一、公平锁与非公平锁1.1 概述公平锁&#xff1a;是指多个线程按照申请锁的顺序来获取锁。非公平锁&#xff1a;是指在多线程获取锁的顺序并不是按照申请锁的顺序&#xff0c;有可能后申请的线程比先申请的线程优先获取到锁&#xff0c;在高并发的情况下&#xff0c;有可能造成…

GoogleNet网络分析与demo实例

参考自 up主的b站链接&#xff1a;霹雳吧啦Wz的个人空间-霹雳吧啦Wz个人主页-哔哩哔哩视频这位大佬的博客 Fun_机器学习,pytorch图像分类,工具箱-CSDN博客 1. GoogLeNet网络详解 GoogLeNet在2014年由Google团队提出&#xff08;与VGG网络同年&#xff0c;注意GoogLeNet中的L大…

解决win10安卓虚拟机每十几分钟蓝屏重启问题

2012年第一次接触android&#xff0c;它的虚拟机是很慢的&#xff0c;如今Intel HAXM 技术为 Android 模拟器加速&#xff0c; 使模拟器运行度媲美真机&#xff0c; 彻底解决模拟器运行慢的问题。问题也是由它而来&#xff0c;因为驱动和系统不兼容造成的。 CPU必须I3及I3以上才…

pg_resetxlog清理的pg_xlog下的WAL日志

PostgreSQL的pg_xlog下有大量日志&#xff0c;空间不足&#xff0c;如何删除&#xff1f; Darren1:postgres:/usr/local/pgsql/data/pg_xlog:>ls 000000010000000000000008.00000028.backup 00000001000000000000009D 0000000100000000000000C9 0000000100000000000000F5…

mysql备份:一,Xtrabackup

资料来自于马哥 注明&#xff1a;此工具不能备份出sql语句。另外只能适用innodb存储引擎。 一、安装 1、简介 Xtrabackup是由percona提供的mysql数据库备份工具&#xff0c;据官方介绍&#xff0c;这也是世界上惟一一款开源的能够对innodb和xtradb数据库进行热备的工具。特点&…

51服务的开启方式

服务开启方式的知识点见博文&#xff1a;http://blog.csdn.net/zengmingen/article/details/49425161步骤&#xff1a; 1、新建Android项目名“51服务的开启方式” 2、新建一个类 MyService&#xff0c;继承 Service 3、在清单文件里配置第二步建的service 4、在Myservice类中覆…

java mysql 存储图片_Java存储图片到Mysql

该楼层疑似违规已被系统折叠 隐藏此楼查看此楼【1】视图层action"${ctx}/web/UserInforServlet?methoduserInforServlet" >更换头像立即提交重置var layer,upload,form;//1-页面数据加载$(function () {//【1】加载&初始化layui模块-弹出层与table数据表格la…

JavaWeb应用配置文件安全解决方案

这里主要说说JavaWeb应用的配置文件安全&#xff0c;通常JavaWeb应用多多少少会有一些配置文件&#xff0c;其中数据源的配置则是关系到数据库的安全&#xff0c;另外还有一些基于文件的权限配置&#xff0c;应用程序的一些系统参数。鉴于这样的情况&#xff0c;如果配置文件被…

java 免费cms_开源 免费 java CMS

Bug修复:1.菜单管理&#xff1a;删除操作按钮后不能直接进行删除菜单操作。2.删除单位时操作记录不显示单位名称问题。3.站点管理&#xff1a;改变所属站点增加改变为一级站点功能&#xff0c;上传非图片logo时虽然提示但仍上传成功问题。4.模板文件管理&#xff1a;点击查看/下…

Android加载大图片不OutOfMemoryError

Android加载图片时&#xff0c;对于分辨率小&#xff0c;配置低的机子&#xff0c;很容易发生OutOfMemoryError。手机的内存比图片的大很多&#xff0c;怎么会这样&#xff1f; 在设置Android虚拟机的内存时&#xff1a; RAM&#xff1a;模拟器的内存空间 VM Heap&#xff1a;…

任务计划、chkconfig工具、systemd管理服务、unit、target

比如备份数据或者重启服务。 crontab -u、-e、-l、-r&#xff08;删除&#xff09; 格式&#xff1a;分 时 日 月 周 user command 文件/var/spool/cron/username 分范围0-59&#xff0c;时范围0-23&#xff0c;日范围1-31&#xff0c;月范围1-12&#xff0c;周1-7 可用格式1-5…

vue打卡日历_Vue日历

new Vue({el: ‘#calendar‘,data: {currentDay: 1,currentMonth: 1,currentYear: 1970,currentWeek: 1,days: [],addDay: [],},created: function() {this.initData(null);var $this this;//请求数据$.ajax({url: "这里填接口名称",type: "POST",data: {…