Reactive Stream 响应式流

一.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
//处理完了!

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值