Reactive-Stream

jvm面向流的库的标准和规范
1.处理可能无限数量的元素
2.有序
3.在组件之间异步传递元素
4.强制性非阻塞背压模式
正压:数据的生产者给消费者压力
背压:生产者产生大量数据,队列缓冲将请求缓存起来,
消费者根据自己能力逐个处理
问题:多线程环境下,线程越多越好还是越少越好
100个线程,4核cpu:
1个核心核心排队了很多线程,线程就要切换
切换就要保留线程(浪费内存,浪费时间)
越多的线程只会产生激烈的竞争
思路:少量的线程一直忙,而不是让大量的线程一直切换或等待
推荐线程数和cpu核心一样
目的:通过全异步的方式,加缓存区构建一个实时的数据流系统
本地化消息系统解决方案:
1.让所有的异步线程能互相监听消息,处理消息,构建实时消息处理
响应式系统:基于异步,消息驱动的全事件回调系统

api组件

1.publisher:发布者,产生数据流
2.subscriber:订阅者,消费数据流
3.subscription:订阅关系
发布者和订阅者之间关键接口,
订阅者通过订阅来表示对发布者产生的数据感兴趣
订阅者可以请求一定数量的元素,也可以取消订阅
4.processor:处理器
是同时实现发布者和订阅者接口的组件
可以接收来自一个发布者的数据,进行处理,并将结果发布给下一个订阅者
处理器在reactor中充当中间环节,代表一个处理阶段
允许在数据流中进行转换过滤和其他操作
命令式编程:全自定义
响应式编程:说清楚要干什么;/最终结果是要怎样
推拉模型:
推:流模式,上游有数据,自动推给下游
拉:迭代器,自己遍历,自己拉取
示例:
1.自定义发布者发布数据MyPublisher

public class MyPublisher extends SubmissionPublisher<String> {

}

2.自定义订阅者,订阅者感兴趣发布者数据MySubscriber

public class MySubscriber implements Flow.Subscriber<String> {

    //订阅关系
    private Flow.Subscription subscription;

    //订阅时 onXxx:在事件发生时执行这个回调
    @Override
    public void onSubscribe(Flow.Subscription subscription) {
        System.out.println("begin subscribe,relation:" + subscription);
        System.out.println("current Thread:" + Thread.currentThread().getName());
        //订阅关系赋值
        this.subscription = subscription;
        //从上游(发布者)中请求一条数据
        subscription.request(1);
    }

    //在下一个元素到达时(接收到新数据),执行回调
    @Override
    public void onNext(String item) {
        System.out.println("subscriber receive new data:" + item);
        System.out.println("current thread :" + Thread.currentThread().getName());
        //背压模式:根据自己能力从缓存中获取
        subscription.request(2);
    }

    //发生错误时,执行回调
    @Override
    public void onError(Throwable throwable) {
        System.out.println(" subscriber error:" + throwable.getMessage());
    }

    //完成是,执行回调
    @Override
    public void onComplete() {
        System.out.println("subscriber finish");
    }

}

3.发布者开始向订阅者发布数据

public static void main(String[] args) throws Exception {
        //1.定义一个发布者(Publisher),负责发布数据
        MyPublisher publisher = new MyPublisher();

        //2.定义一个订阅者,订阅者感兴趣发布者数据
        MySubscriber subscriber = new MySubscriber();

        //3.发布者和订阅者绑定在一起,订阅者会给上游(发布者)一个信号,让发布者可以发布元素给下游(背压模式)
        publisher.subscribe(subscriber);

        //4.发布数据
        for (int i = 0; i < 10; i++) {
            //发布者向消息队列(缓冲区)发布10条数据
            publisher.submit("p-" + i);
        }

        //5.发布者数据发布完成
        publisher.close();

        //效果:发布者有数据,订阅者就会拿到
        Thread.sleep(20000);
    }

结果:
发布订阅结果

四大核心组件

定义处理器MyProcessor

public class MyProcessor extends SubmissionPublisher<String> implements Flow.Processor<String,String> {

    //保存绑定关系
    private Flow.Subscription subscription;

    @Override
    public void onSubscribe(Flow.Subscription subscription) {
        System.out.println("processor bind finish...");
        this.subscription = subscription;
        subscription.request(1L);//找上游发布者要一个数据
    }

    //数据到达触发
    @Override
    public void onNext(String item) {
        System.out.println("processor get data:"+item);
		item += "new data--" + item;
        this.submit(item);//将加工后的数据发出去
        subscription.request(1L);//再要新数据,继续加工发出去
    }

    @Override
    public void onError(Throwable throwable) {

    }

    @Override
    public void onComplete() {

    }
}

将发布者和处理器绑定
绑定操作:发布者记住了所有订阅者都有谁,有数据后,给所有订阅者把数据通过过去

        //3.发布者和订阅者绑定在一起,订阅者会给上游(发布者)一个信号,让发布者可以发布元素给下游(背压模式)
        //定义中间操作
        MyProcessor processor = new MyProcessor();
        publisher.subscribe(processor);//发布者和处理器绑定,此时处理器相当于订阅者
        publisher.subscribe(subscriber);//处理器和订阅者绑定,此时处理器相当于发布者

增加中间处理器

总结:

1.底层:基于数据缓冲队列+消息驱动模型+异步回调机制
2.编码:流式编程+链式调用+声明式Api
3.效果:优雅全异步+消息实时处理+高吞吐量+占用少量资源

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值