<div class="article-content">
<h2 class="heading">前言</h2>
<p><strong>背压(Backpressure)可能是所有想要深入运用RxJava的朋友必须理解的一个概念</strong>。</p>
<p>关于它的介绍,我本意是想写在RxJava2.0更新介绍的文章里的,可是写着写着发现,要完整介绍这个概念需要花费的篇幅太长,恰好目前对于背压的介绍文章比较少,所以决定单独拿出来,自成一篇。而关于RxJava2.0的文章修改之后就会发出来和大家探讨。</p>
<p>如果对于RxJava不是很熟悉,那么在这篇文章之前,我希望大家先看看那篇<a href="https://link.juejin.im?target=http%3A%2F%2Fgold.xitu.io%2Fpost%2F580103f20e3dd90057fc3e6d">关于Rxjava最友好的文章</a>,可以帮助大家很顺畅的了解RxJava。</p>
<hr>
<h2 class="heading">从场景出发</h2>
<p>让我们先忘掉背压(Backpressure)这个概念,从RxJava一个比较常见的工作场景说起。</p>
<p>RxJava是一个观察者模式的架构,当这个架构中被观察者(Observable)和观察者(Subscriber)处在不同的线程环境中时,由于者各自的工作量不一样,导致它们产生事件和处理事件的速度不一样,这就会出现两种情况:</p>
<ul><li>被观察者产生事件慢一些,观察者处理事件很快。那么观察者就会等着被观察者发送事件,<strong>(好比观察者在等米下锅,程序等待,这没有问题)</strong>。</li><li>被观察者产生事件的速度很快,而观察者处理很慢。那就出问题了,如果不作处理的话,事件会堆积起来,最终挤爆你的内存,导致程序崩溃。<strong>(好比被观察者生产的大米没人吃,堆积最后就会烂掉)</strong>。</li></ul>
<p>下面我们用代码演示一下这种崩溃的场景:</p>
<pre class="blockcode"><code class="hljs bash copyable">//被观察者在主线程中,每1ms发送一个事件
Observable.interval(1, TimeUnit.MILLISECONDS)
//.subscribeOn(Schedulers.newThread())
//将观察者的工作放在新线程环境中
.observeOn(Schedulers.newThread())
//观察者处理每1000ms才处理一个事件
.subscribe(new Action1<Long>() {
@Override
public void call(Long aLong) {
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
Log.w(<span class="hljs-string">"TAG"</span>,<span class="hljs-string">"---->"</span>+aLong);
}
});
<span class="copy-code-btn">复制代码</span></code></pre>
<p>在上面的代码中,<strong>被观察者发送事件的速度是观察者处理速度的1000倍</strong></p>
<p>这段代码运行之后:</p>
<pre class="blockcode"><code class="hljs bash copyable"> ...
Caused by: rx.exceptions.MissingBackpressureException
...
...
<span class="copy-code-btn">复制代码</span></code></pre>
<p>抛出MissingBackpressureException往往就是因为,被观察者发送事件的速度太快,而观察者处理太慢,而且你还没有做相应措施,所以报异常。</p>
<p>而这个MissingBackpressureException异常里面就包含了Backpressure这个单词,看来背压肯定和这种异常情况有关系。</p>
<p>那么背压(Backpressure)到底是什么呢?</p>
<hr>
<h2 class="heading">关于背压(Backpressure)</h2>
<p>我这两天翻阅了大量的中文和英文资料,我发现中文资料中,很多人对于背压(Backpressure)的理解是有很大问题的,有的人把它看作一个需要避免的问题,或者程序的异常,有的人则干脆避而不谈,模棱两可,着实让人尴尬。</p>
<p>通过参考和对比大量的相关资料,我在这里先对背压(Backpressure)做一个明确的定义:<strong>背压是指在异步场景中,被观察者发送事件速度远快于观察者的处理速度的情况下,一种告诉上游的被观察者降低发送速度的策略</strong></p>
<p>简而言之,<strong>背压是流速控制的一种策略</strong>。</p>
<p>需要强调两点:</p>
<ul><li>背压策略的一个前提是<strong>异步环境</strong>,也就是说,被观察者和观察者处在不同的线程环境中。</li><li>背压(Backpressure)并不是一个像flatMap一样可以在程序中直接使用的操作符,他只是一种控制事件流速的策略。</li></ul>
<p>那么我们再回看上面的程序异常就很好理解了,就是当被观察者发送事件速度过快的情况下,我们没有做流速控制,导致了异常。</p>
<p>那么背压(Bac |
|