Rxjava - 背压

254 阅读2分钟

产出的原因

当上下游在不同的线程中,通过Observable发射,处理,响应数据流时,如果上游发射数据的速度快于下游接收处理数据的速度,这样对于那些没来得及处理的数据就会造成积压,这些数据既不会丢失,也不会被垃圾回收机制回收,而是存放在一个异步缓存池中,如果缓存池中的数据一直得不到处理,越积越多,最后就会造成内存溢出,这便是响应式编程中的背压(backpressure)问题

解决思路

响应式拉取是观察者主动去被观察者那里拉取事件,而被观察者则是被动等待通知再发射事件。

背压策略

  • MISSING(MissingEmitter)

    在此策略下,通过Create方法创建的Flowable相当于没有指定背压策略,不会对通过onNext发射的数据做缓存或丢弃处理,需要下游通过背压操作符

  • ERROR(ErrorAsyncEmitter)

    在此策略下,如果放入Flowable的异步缓存池中的数据超限了,则会抛出MissingBackpressureException异常

  • BUFFER(BufferAsyncEmitter)

    部维护了一个缓存池SpscLinkedArrayQueue,其大小不限,此策略下,如果Flowable默认的异步缓存池满了,会通过此缓存池暂存数据,它与Observable的异步缓存池一样,可以无限制向里添加数据,不会抛出MissingBackpressureException异常,但会导致OOM

  • DROP(DropAsyncEmitter)

    在此策略下,如果Flowable的异步缓存池满了,会丢掉上游发送的数据

  • DROP(LatestAsyncEmitter)

    与Drop策略一样,如果缓存池满了,会丢掉将要放入缓存池中的数据,不同的是,不管缓存池的状态如何,LATEST都会将最后一条数据强行放入缓存池中,来保证观察者在接收到完成通知之前,能够接收到Flowable最新发射的一条数据

Subscription

响应式拉取方式,来设置下游对数据的请求数量,上游可以根据下游的需求量,按需发送数据,如果不显示调用request()则默认下游的需求量为零,所以运行上面的代码后,上游Flowable发射的数据不会交给下游Subscriber处理。