RxJava笔记4:背压Backpressure

概念

我们知道上游发布事件,下游处理事件,有没有想过,如果上游发布事件很快,而下游处理事件很慢会发生什么情况,看下面代码:

Observable.create(new ObservableOnSubscribe<Integer>() {
    @Override
    public void subscribe(ObservableEmitter<Integer> e) throws Exception {
        for (int i = 0;; i++) {
            System.out.println("emit i " + i);
            e.onNext(i);
        }
    }
}).subscribe(new Consumer<Integer>() {
    @Override
    public void accept(Integer s) throws Exception {
        Thread.sleep(500);
        System.out.println("onNext " + s);
    }
});
System.out: emit i 0
System.out: onNext 0
System.out: emit i 1
System.out: onNext 1
System.out: emit i 2
System.out: onNext 2
···

上游是个死循环,不断发数据,下游处理数据时睡眠了500毫秒,但是从输出结果发现上游来一个,下游便处理一个,上游与下游同步执行。其实这样的结果可想而知是因为上游和下游工作在同一线程,同步执行,下游睡眠结束后,上游才再次发送数据。好,我们现在把他们放到不同线程执行下试试:

Observable.create(new ObservableOnSubscribe<Integer>() {
    @Override
    public void subscribe(ObservableEmitter<Integer> e) throws Exception {
        for (int i = 0; ; i++) {
            e.onNext(i);
        }
    }
}).observeOn(Schedulers.io()).subscribe(new Consumer<Integer>() {
    @Override
    public void accept(Integer s) throws Exception {
        Thread.sleep(500);
        System.out.println("onNext " + s);
    }
});

下图是运行这段代码,通过 android studio 的 profiler 看到的实时内存大小:
在这里插入图片描述
可以看到,当上游与下游不在同一线程,异步执行时,如果上游发送事件很快,下游不能及时处理时,就会导致应用占用内存非常大,甚至OOM。
既然问题是因为上游发送事件大于下游处理事件,那我们是否可以控制上游发送的速度来解决的? 有几个操作符确实是可以控制, 上篇博文中提到的sample,throttleFirst,debounce 操作符都可以,但是它们都有个问题,它们并不是真正去控制上游的速度,只是丢弃了很多事件,只接受时间范围内的某一个事件。另外还有一个 buffer 操作符 ,它可以先将上游的事件放到缓冲池里面,等达到指定数量后才发给下游。

Observable.range(1, 1000)
        .subscribeOn(Schedulers.io())
        .buffer(10)
        .observeOn(Schedulers.io())
        .subscribe(System.out::println);
        
System.out: [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
System.out: [11, 12, 13, 14, 15, 16, 17, 18, 19, 20]
System.out: [21, 22, 23, 24, 25, 26, 27, 28, 29, 30]
...

那有没有真正可以控制上游的速度,响应式拉取事件,下游能处理多少事件就发送多少事件,或者说下游处理一个,上游发送一个,的方法呢?
那就是 背压

背压就是解决异步环境下,上游与下游效率不一样时的方法策略。

Observable 是不支持背压的,而后来的 Flowable 支持,这是 Observable 和 Flowable 主要的区别。

下一篇博文中将介绍 Flowable 。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值