7.2 Flowable 背压

1.背压的产生

Backpressure(背压)是指在异步场景中,被观察者发送事件速度远快于观察者的处理速度的情况下,一种告诉上游的被观察者降低发送速度的策略。在 Observable/Observer 组合的使用中是不支持背压的,下面通过一个例子来看一下这种场景:

Observable.create(new ObservableOnSubscribe<Integer>() {
    @Override
    public void subscribe(@NonNull ObservableEmitter<Integer> e) throws Exception {
        int i = 0;
        while(i < Long.MAX_VALUE){
            e.onNext(i);
            i++;
        }
    }
	}).subscribeOn(Schedulers.newThread())
        .observeOn(Schedulers.newThread())
        .subscribe(new Consumer<Integer>() {
            @Override
            public void accept(Integer integer) throws Exception {
                Thread.sleep(1000);
                Log.e("Test","i = "+integer);
            }
        });

2.Flowable

Flowable 就是为了解决背压问题的产物,因此才会把它们和 Observable/Observer 区分开来使用。
由于基于Flowable发射的数据流,以及对数据加工处理的各操作符都添加了背压支持,附加了额外的逻辑,其运行效率要比 Observable 低得多。
因为只有上下游运行在各自的线程中,且上游发射数据速度大于下游接收处理数据的速度时,才会产生背压问题。
所以,如果能够确定上下游在同一个线程中工作,或者上下游工作在不同的线程中,而下游处理数据的速度高于上游发射数据的速度,则不会产生背压问题,就没有必要使用 Flowable,以免影响性能。

Flowable.create(new FlowableOnSubscribe<Integer>() {
    @Override
    public void subscribe(@NonNull FlowableEmitter<Integer> e) throws Exception {
        int i = 0;
        while(i < Long.MAX_VALUE){
            e.onNext(i);
            i++;
        }
    }
}, BackpressureStrategy.DROP)
        .subscribeOn(Schedulers.io())
        .observeOn(Schedulers.newThread())
        .subscribe(new Subscriber<Integer>() {
            @Override
            public void onSubscribe(Subscription s) {
                s.request(Long.MAX_VALUE);
            }
            @Override
            public void onNext(Integer integer) {
                try {
                    Thread.sleep(100);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                Log.e("Test","i = "+integer);
            }
            @Override
            public void onError(Throwable t) {
            }
            @Override
            public void onComplete() {
            }
        });

这里注意三点:

  • Flowable.create 参数中多了个 BackpressureStrategy。
  • onSubscribe 回调的参数不是 Disposable 而是 Subscription。而且需要调用 Subscription.request 发起数据请求,否则Subscriber不会接受数据。
  • 数据发射器是 FlowableEmitter 而不是 ObservableEmitter。

3.背压策略(BackpressureStrategy)

Flowable 的异步缓存池不同于 Observable,Observable的异步缓存池没有大小限制,可以无限制向里添加数据,直至OOM,而 Flowable 的异步缓存池有个固定容量,其大小为128。
BackpressureStrategy 的作用便是用来设置 Flowable 异步缓存池中的存储数据超限时的策略。
BackpressureStrategy 提供了一下几种背压策略:

  • MISSING:这种策略模式下相当于没有指定任何的背压策略,不会对数据做缓存或丢弃处理,需要下游通过背压操作符(onBackpressureBuffer()/onBackpressureDrop()/onBackpressureLatest())指定背压策略。
  • ERROR:这种策略模式下如果缓存池中的数据超限了,则会抛出 MissingBackpressureException 异常
  • BUFFER:这种策略模式下没有为异步缓存池限制大小,可以无限制向里添加数据,不会抛出 MissingBackpressureException 异常,但会导致OOM。
  • DROP:这种策略模式下如果异步缓存池满了,会丢掉将要放入缓存池中的数据。
  • LATEST:这种策略模式下与 Drop 策略一样,如果缓存池满了,会丢掉将要放入缓存池中的数据,不同的是,不管缓存池的状态如何,LATEST都会将最后一条数据强行放入缓存池中。

参考:https://www.heqiangfly.com/2017/10/14/open-source-rxjava-guide-flowable/

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值