当前位置: 首页 > news >正文

Java 9 响应式流(Reactive Streams)

前言

首先出现响应式编程理念,然后出现响应式编程实现,再然后出现响应式规范,响应流主要解决处理元素流的问题—如何将元素流从发布者传递到订阅者,不而不需要发布者阻塞,或者要求订阅者有无限的缓冲区,有限的缓冲区在到达缓冲上界的时候,对到达的元素进行丢弃或者拒绝,订阅者可以异步通知发布者降低或提升数据生产发布的速率,它是响应式编程实现效果的核心特点。

而响应式规范则是一种倡议,遵循此倡议的系统可以让数据在各个响应式系统中都实现响应式的处理数据,规范在Java中的形式就是接口,也就是我们本篇的主题Flow 类,对于一项标准而言,它的目的自然是用更少的协议来描述交互。

Java 9 的Flow统一了规范

响应式流从2013年开始,作为提供非阻塞背压的异步流处理标准的倡议。 它旨在解决处理元素流的问题——如何将元素流从发布者传递到订阅者,而不需要发布者阻塞,或订阅者有无限制的缓冲区或丢弃。

响应式流模型非常简单——订阅者向发布者发送多个元素的异步请求。 发布者向订阅者异步发送多个或稍少的元素。

在2015年,出版了用于处理响应式流的规范和Java API。 有关响应式流的更多信息,请访问http://www.reactive-streams.org/。 Java API 的响应式流只包含四个接口:

Publisher<T>
Subscriber<T>
Subscription
Processor<T,R>

发布者(publisher)是潜在无限数量的有序元素的生产者。 它根据收到的要求向当前订阅者发布(或发送)元素。

订阅者(subscriber)从发布者那里订阅并接收元素。 发布者向订阅者发送订阅令牌(subscription token)。 使用订阅令牌,订阅者从发布者哪里请求多个元素。 当元素准备就绪时,发布者向订阅者发送多个或更少的元素。 订阅者可以请求更多的元素。 发布者可能有多个来自订阅者的元素待处理请求。

订阅(subscription)表示订阅者订阅的一个发布者的令牌。 当订阅请求成功时,发布者将其传递给订阅者。 订阅者使用订阅令牌与发布者进行交互,例如请求更多的元素或取消订阅。

处理者(processor)充当订阅者和发布者的处理阶段。 Processor接口继承了PublisherSubscriber接口。 它用于转换发布者——订阅者管道中的元素。 Processor<T,R>订阅类型T的数据元素,接收并转换为类型R的数据,并发布变换后的数据。 

JDK 9在java.util.concurrent包中提供了一个与响应式流兼容的API,它在java.base模块中。 API由两个类组成:

Flow
SubmissionPublisher<T>

Flow类是final的。 它封装了响应式流Java API和静态方法。 由响应式流Java API指定的四个接口作为嵌套静态接口包含在Flow类中:

Flow.Processor<T,R>
Flow.Publisher<T>
Flow.Subscriber<T>
Flow.Subscription

这四个接口包含与上面代码所示的相同的方法。 Flow类包含defaultBufferSize()静态方法,它返回发布者和订阅者使用的缓冲区的默认大小。 目前,它返回256。

SubmissionPublisher<T>类是Flow.Publisher<T>接口的实现类。 该类实现了AutoCloseable接口,因此可以使用try-with-resources块来管理其实例。 JDK 9不提供Flow.Subscriber<T>接口的实现类; 需要自己实现。 但是,SubmissionPublisher<T>类包含可用于处理此发布者发布的所有元素的consume(Consumer<? super T> consumer)方法。

简单的案例

import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Flow;
import java.util.concurrent.SubmissionPublisher;
import java.util.function.Consumer;/*** 使用java9 Flow中的API实现响应式编程*/
public class Reactor03 {static class SampleSubScriber<T> implements Flow.Subscriber<T> {final Consumer<? super T> consumer;Flow.Subscription subscription;SampleSubScriber(Consumer<? super T> consumer) {this.consumer = consumer;}@Overridepublic void onSubscribe(Flow.Subscription subscription) {System.out.println("建立订阅关系");this.subscription = subscription;// 订阅者只处理两条信息subscription.request(2);}@Overridepublic void onNext(T item) {System.out.println("收到发送者的消息"+ item);consumer.accept(item);// 消费过后,还可以继续要求发布者发送消息// subscription.request(2);// 如果不要求发布者发送消息,由于onSubscribe()设置了只处理2条消息,那边发布者就不会继续发布第三条了。}@Overridepublic void onError(Throwable throwable) {throwable.printStackTrace();}@Overridepublic void onComplete() {}}public static void main(String[] args) {SampleSubScriber subScriber = new SampleSubScriber<>(msg -> System.out.println("hello ...... " + msg));ExecutorService executorService = Executors.newFixedThreadPool(1);SubmissionPublisher<Boolean> submissionPublisher = new SubmissionPublisher<>(executorService, Flow.defaultBufferSize());submissionPublisher.subscribe(subScriber);submissionPublisher.submit(true);submissionPublisher.submit(true);submissionPublisher.submit(true);executorService.shutdown();}
}

感谢下述博文的作者:

参考资料:

https://www.cnblogs.com/IcanFixIt/p/7245377.html

相关文章:

  • 回显服务器
  • day07-实战-今日指数
  • 如何在 Angular 中为响应式表单创建自定义验证器
  • 如何对线上项目Debug
  • C语言希尔排序详解!!!速过
  • redis的缓存穿透,缓存并发,缓存雪崩,缓存问题及解决方案
  • 【MySQL】事务的一致性究竟怎么理解?
  • Spring Boot项目打包及依赖管理-瘦身
  • css中选择器的优先级
  • flink operator 1.7 更换日志框架log4j 到logback
  • 最近火的一键穿衣AI,这款服装设计软件也不赖
  • 【动态规划专栏】专题二:路径问题--------6.地下城游戏
  • 2024-02-20(数位DP)
  • RuntimeError: CUDA out of memory.【多种场景下的解决方案】
  • Delphi语言教程
  • 「前端早读君006」移动开发必备:那些玩转H5的小技巧
  • ➹使用webpack配置多页面应用(MPA)
  • js如何打印object对象
  • k8s如何管理Pod
  • niucms就是以城市为分割单位,在上面 小区/乡村/同城论坛+58+团购
  • Redash本地开发环境搭建
  • REST架构的思考
  • session共享问题解决方案
  • vue.js框架原理浅析
  • webpack项目中使用grunt监听文件变动自动打包编译
  • 百度小程序遇到的问题
  • 半理解系列--Promise的进化史
  • 前端学习笔记之观察者模式
  • 如何将自己的网站分享到QQ空间,微信,微博等等
  • 自制字幕遮挡器
  • 如何在招聘中考核.NET架构师
  • ​​​​​​​ubuntu16.04 fastreid训练过程
  • ​软考-高级-系统架构设计师教程(清华第2版)【第20章 系统架构设计师论文写作要点(P717~728)-思维导图】​
  • ​直流电和交流电有什么区别为什么这个时候又要变成直流电呢?交流转换到直流(整流器)直流变交流(逆变器)​
  • #调用传感器数据_Flink使用函数之监控传感器温度上升提醒
  • (6)STL算法之转换
  • (arch)linux 转换文件编码格式
  • (翻译)Entity Framework技巧系列之七 - Tip 26 – 28
  • (分享)一个图片添加水印的小demo的页面,可自定义样式
  • (更新)A股上市公司华证ESG评级得分稳健性校验ESG得分年均值中位数(2009-2023年.12)
  • (一)ClickHouse 中的 `MaterializedMySQL` 数据库引擎的使用方法、设置、特性和限制。
  • .NET Core SkiaSharp 替代 System.Drawing.Common 的一些用法
  • .NET DevOps 接入指南 | 1. GitLab 安装
  • .NET 发展历程
  • .NET 指南:抽象化实现的基类
  • .NET 中让 Task 支持带超时的异步等待
  • .NET开发人员必知的八个网站
  • .Net转Java自学之路—SpringMVC框架篇六(异常处理)
  • .set 数据导入matlab,设置变量导入选项 - MATLAB setvaropts - MathWorks 中国
  • @RequestBody的使用
  • @拔赤:Web前端开发十日谈
  • [120_移动开发Android]008_android开发之Pull操作xml文件
  • [C#]获取指定文件夹下的所有文件名(递归)
  • [C/C++]_[初级]_[关于编译时出现有符号-无符号不匹配的警告-sizeof使用注意事项]
  • [ERROR ImagePull]: failed to pull image k8s.gcr.io/kube-controller-manager失败