一.JDK9 Reactive Stream基础概念
1.概念
- 基于发布订阅者模式处理规范(机制),在JDK中真正叫法是FlowAPI。
2.背压(backpress)
- 背压指的发布者和订阅者之间的互动
- 订阅者可以告诉发布者自己需要多少数据,可以调节数据流量,不会导致发布者发布数据过多导致数据浪费或压垮订阅者
二.Reactive Stream主要接口【Flow类】
Reactive Stream主要接口如下
1.Publisher<T>接口
发布者
subscribe(Subscriber<? super T>):void
:保证发布者和订阅者之间通过此方法建立订阅关系
2.Subscriber<T>
订阅者
onSubscribe(Subscription):void
:第一此签署订阅关系,输入就是Subscription对象onNext(T):void
:接收到一条数据onError(Throwable):void
:数据出错onComplete():void
:数据处理完了
3.Subscription
发布者与订阅者之间的关系
request(long):void
:告诉发布者需要多少资源cancel():void
4.Processor<T,R>
接口继承了Publisher和Subscriber,表示既可以做消费者,又可以做发布者,承担中间角色
defaultBufferSize():int
三.实例演示
1.实例代码
public class FlowDemo {
public static void main(String[] args) throws Exception {
//1.定义发布者,发布的数据类型是Integer
//直接使用jdk自带的SubmissionPublisher,它实现了Publisher接口
SubmissionPublisher<Integer> publisher = new SubmissionPublisher<Integer>();
//2.定义订阅者
Subscriber<Integer> subscriber = new Subscriber<Integer>() {
private Subscription subscription;
@Override
public void onSubscribe(Subscription subscription) {
//保存订阅关系,需要用它来给发布者响应
this.subscription = subscription;
//请求一个数据
this.subscription.request(1);
}
@Override
public void onNext(Integer item) {
//接受一个数据,处理
System.out.println("接收到数据:"+item);
//处理完调用request再请求一个数据
this.subscription.request(1);
//或者 已经达到了目标,调用cancel告诉发布者不再接受数据了
//this.subscription.cancel();
}
@Override
public void onError(Throwable throwable) {
//出现了异常(例如处理数据的时候产生了异常)
throwable.printStackTrace();
//我们可以告诉发布者,后面不接受数据了
this.subscription.cancel();
}
@Override
public void onComplete() {
//全部数据处理完了(发布者关闭了)
System.out.println("处理完了!");
}
}
//3.发布者和订阅者之间建立订阅关系
publisher.subscribe(subscriber);
//4.生产数据,并发布
//这里忽略数据产生过程
int data = 111;
publisher.submit(data);//发布数据
//5.结束后 关闭发布者
//正式环境 应该放finally或者使用try-resouce确保关闭
publisher.close();//关闭发布者
}
}
2.添加Processor中转站实例代码
/**
* Processor需要继承SubmissionPublisher并实现Processor接口
* 输入数据Integer,过滤小于0的,然后转换成字符串发布出去
*/
class MyProcessor extends SubmissionPublisher<String> implements Processor<Integer,String>{
private Subscription subscription;
@Override
public void onSubscribe(Subscription subscription) {
//保存订阅关系,需要用它来给发布者响应
this.subscription = subscription;
//请求一个数据
this.subscription.request(1);
}
@Override
public void onNext(Integer item) {
//接受到一个数据,处理
System.out.println("处理器接收到数据:" +item);
//过滤掉小于0的,然后发布出去
if(item>0) {
this.submit("转换后的数据:"+item);
}
}
@Override
public void onError(Throwable throwable) {
//出现了异常(例如处理数据的时候产生了异常)
throwable.printStackTrace();
//我们可以告诉发布者,后面不接受数据了
this.subscription.cancel();
}
@Override
public void onComplete() {
//全部数据处理完了(发布者关闭了)
System.out.println("处理器处理完了");
//关闭发布者
this.close();
}
}
public class FlowDemo2 {
public static void main(String[] args) throws Exception {
//1.定义发布者,发布的数据类型是Integer
//直接使用jdk自带的SubmissionPublisher,它实现了Publisher接口
SubmissionPublisher<Integer> publisher = new SubmissionPublisher<Integer>();
//2.定义处理器,对数据进行过滤,并转换为String类型
MyProcessor processor = new MyProcessor();
//3.发布者和处理器建立订阅关系
publisher.subscribe(processor);
//4.定义最终订阅者,消费String类型数据
Subscriber<Integer> subscriber = new Subscriber<Integer>() {
private Subscription subscription;
@Override
public void onSubscribe(Subscription subscription) {
//保存订阅关系,需要用它来给发布者响应
this.subscription = subscription;
//请求一个数据
this.subscription.request(1);
}
@Override
public void onNext(Integer item) {
//接受一个数据,处理
System.out.println("接收到数据:"+item);
//处理完调用request再请求一个数据
this.subscription.request(1);
//或者 已经达到了目标,调用cancel告诉发布者不再接受数据了
//this.subscription.cancel();
}
@Override
public void onError(Throwable throwable) {
//出现了异常(例如处理数据的时候产生了异常)
throwable.printStackTrace();
//我们可以告诉发布者,后面不接受数据了
this.subscription.cancel();
}
@Override
public void onComplete() {
//全部数据处理完了(发布者关闭了)
System.out.println("处理完了!");
}
}
//5.处理器和最终订阅者建立订阅关系
processor.subscribe(subscriber);
//6.生产数据,并发布
//这里忽略数据产生过程
//submit是一个block(阻塞)方法
publisher.submit(-111);//订阅者的缓冲池是256个单位长度,发布者生成256个数据后submit就被阻塞,如果订阅者的缓冲池慢了发布者就会等待订阅者消费,从而实现调节生产者生成数据的速度
publisher.submit(111);
//7.结束后 关闭发布者
//正式环境 应该放finally或者使用try-resouce确保关闭
publisher.close();//关闭发布者
}
}
//输出结果
//处理器接受到数据:-111
//处理器接收到数据:111
//处理器处理完了!
//接收到数据:转换后的数据:111
//处理完了!