關(guān)于 RxJava2 backpressure的一些理解

RxJava2 中的背壓

在RxJava2里摘能,引入了Flowable這個類來處理backpressure湾蔓,而Observable不包含backpressure處理洲劣。Flowable的三種Backpressure策略:

  • BackpressureStrategy.BUFFER
    onBackpressureBuffer是不丟棄數(shù)據(jù)的處理方式瓢颅。把上游收到的全部緩存下來碘饼,等下游來請求再發(fā)給下游熙兔。相當(dāng)于一個水庫。但上游太快艾恼,水庫(buffer)就會溢出住涉。
  • BackpressureStrategy.DROP 與 BackpressureStrategy.LATEST
    Drop 和Latest 類似,都會丟棄數(shù)據(jù)钠绍,下游通過request請求產(chǎn)生令牌給上游舆声,上游接收到多少令牌,就發(fā)送多少柳爽,當(dāng)令牌為0的時候媳握,上游開始丟棄數(shù)據(jù)。區(qū)別在于磷脯,drop直接丟棄數(shù)據(jù)不緩存數(shù)據(jù)蛾找。而latest緩存最新的一條數(shù)據(jù),當(dāng)上游收到令牌赵誓,就把緩存的上一條“最新”數(shù)據(jù)發(fā)送給下游打毛。

例如 :

 Flowable<Integer> flowable =
                Flowable.create((FlowableOnSubscribe<Integer>) e -> {
                    for (int i = 0; i < Integer.MAX_VALUE; i++) {
                        Log.d(TAG, "onNext  : " + i);
                        e.onNext(i);
                        Thread.sleep(10);
                    }
                }, BackpressureStrategy.DROP).subscribeOn(Schedulers.io())
                        .observeOn(AndroidSchedulers.mainThread());

Flowable以10毫秒一次派發(fā)數(shù)據(jù),注意我們讓Flowable和訂閱者運行在不同的線程俩功,這樣才能看出生產(chǎn)與消費在不同效率下時的差異性隘冲,如果Flowable和訂閱者在同一線程,背壓是沒什么意義的绑雄。假設(shè)訂閱他們的方法都是:

Subscription mSubscription;
flowable.subscribe(new Subscriber<Integer>() {
            @Override
            public void onSubscribe(Subscription subscription) {
                mSubscription = subscription;
            }

            @Override
            public void onNext(Integer integer) {
                Log.d(TAG, "onNext: " + integer);
            }

            @Override
            public void onError(Throwable throwable) {

            }

            @Override
            public void onComplete() {

            }
        });

我們在onSubscribe中保存了Subscription ,以后 方便我們可以在任何時候request 數(shù)據(jù)奥邮。我們添加一個按鈕万牺,以實現(xiàn)手動request數(shù)據(jù) 罗珍,代碼如下:

if(mSubscription != null) {
  mSubscription.request(64);
}

我們一開始request 64個數(shù)據(jù),我們啟動Flowable后脚粟,隔一段時間才點擊request , log打印 0 ~ 63 :

D/SimpleExampleActivity: onNext: 0
D/SimpleExampleActivity: onNext: 1
D/SimpleExampleActivity: onNext: 2
...
D/SimpleExampleActivity: onNext: 63
D/SimpleExampleActivity: onNext: 64

隔一段時間第二次點擊request , log打印 64~ 127 :

D/SimpleExampleActivity: onNext: 64
D/SimpleExampleActivity: onNext: 65
D/SimpleExampleActivity: onNext: 66
...
D/SimpleExampleActivity: onNext: 126
D/SimpleExampleActivity: onNext: 127

隔一段時間第三次點擊request , log打印 1243~ 1306:

D/SimpleExampleActivity: onNext: 1243
D/SimpleExampleActivity: onNext: 1244
D/SimpleExampleActivity: onNext: 1245
...
D/SimpleExampleActivity: onNext: 1304
D/SimpleExampleActivity: onNext: 1305
D/SimpleExampleActivity: onNext: 1306

我們使用是BackpressureStrategy.DROP 覆旱, 與就是 直接丟棄數(shù)據(jù)不緩存數(shù)據(jù) 『宋蓿可是我們一開始隔了點時間再request時扣唱,還是打印從 0 ~ 127 , 這說明 Flowable 本身就會存儲緩存 128 個數(shù)據(jù)团南,超過128個后執(zhí)行我們的策略噪沙,也就是丟棄。所以 1243~ 1306 其實是我們在第二次點擊后吐根,重新緩存的128數(shù)據(jù)正歼。如果我們換成 BackpressureStrategy.BUFFER , 那么不管你點擊多少次拷橘,數(shù)據(jù)都是連續(xù)的局义,因為 BackpressureStrategy.BUFFER 策略會把數(shù)據(jù)一直放到內(nèi)存中,直到發(fā)生OutOfMemoryError冗疮。
我們現(xiàn)在修改request 的數(shù)目 萄唇,改成 每次 request 96 個 , 代碼如下 :

if(mSubscription != null) {
  mSubscription.request(96);
}

第一次點擊request , log打印 0 ~ 95 , 沒什么問題

D/SimpleExampleActivity: onNext: 0
D/SimpleExampleActivity: onNext: 1
D/SimpleExampleActivity: onNext: 2
...
D/SimpleExampleActivity: onNext: 94
D/SimpleExampleActivity: onNext: 95

隔一段時間第二次點擊request , log打印 96 ~ 127 , 188 ~ 251 :

D/SimpleExampleActivity: onNext: 96
D/SimpleExampleActivity: onNext: 97
D/SimpleExampleActivity: onNext: 98
...
D/SimpleExampleActivity: onNext: 126
D/SimpleExampleActivity: onNext: 127
D/SimpleExampleActivity: onNext: 188
D/SimpleExampleActivity: onNext: 189
...
D/SimpleExampleActivity: onNext: 250
D/SimpleExampleActivity: onNext: 251

隔一段時間第三次點擊request , log打印 252 ~ 283 , 650 ~ 713:

D/SimpleExampleActivity: onNext: 252
D/SimpleExampleActivity: onNext: 253
...
D/SimpleExampleActivity: onNext: 282
D/SimpleExampleActivity: onNext: 283
D/SimpleExampleActivity: onNext: 650
D/SimpleExampleActivity: onNext: 651
...
D/SimpleExampleActivity: onNext: 712
D/SimpleExampleActivity: onNext: 713

我們可以看到第二次术幔、第三次時打印的數(shù)據(jù)出現(xiàn)了中斷的情況另萤。我們知道Flowable 默認會緩存 127個數(shù)據(jù),那么第一次點擊之后應(yīng)該剩下 128 - 96 = 32個 特愿, 所以第二次首先打印 96 ~ 127 仲墨, 之后再打印 188 ~ 251 64個數(shù)據(jù)。第三次又打印了 252 ~ 283 32個數(shù)據(jù)揍障。第二次打印中斷之后打印的 64個數(shù)據(jù) 加上 第三次打印中斷前打印的 32個目养,剛好是 96個數(shù)據(jù),也就是打印中斷的時間點的數(shù)據(jù)剛好是96個毒嫡。
這個96就是Flowable 重新去拉取緩存的限制癌蚁,這是在源碼上設(shè)定的,就是說首先緩存了 128個數(shù)據(jù)之后兜畸,被消費了96個數(shù)據(jù)時才會重新緩存努释。所以在第二次時,從127后就打印了 188咬摇,因為這個188是在第一次點擊之后就重新緩存了伐蒂。

總結(jié)

Flowable 有三種Backpressure策略,分別是BackpressureStrategy.BUFFER肛鹏、BackpressureStrategy.DROP 和 BackpressureStrategy.LATEST逸邦。默認會緩存 127個數(shù)據(jù)恩沛,被消費了96個數(shù)據(jù)后才會重新緩存。

參考

探索專為 Android 而設(shè)計的 RxJava 2
RxJava2 vs RxJava1

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末缕减,一起剝皮案震驚了整個濱河市雷客,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌桥狡,老刑警劉巖搅裙,帶你破解...
    沈念sama閱讀 222,252評論 6 516
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異裹芝,居然都是意外死亡部逮,警方通過查閱死者的電腦和手機,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 94,886評論 3 399
  • 文/潘曉璐 我一進店門局雄,熙熙樓的掌柜王于貴愁眉苦臉地迎上來甥啄,“玉大人,你說我怎么就攤上這事炬搭◎诶欤” “怎么了?”我有些...
    開封第一講書人閱讀 168,814評論 0 361
  • 文/不壞的土叔 我叫張陵宫盔,是天一觀的道長融虽。 經(jīng)常有香客問我,道長灼芭,這世上最難降的妖魔是什么有额? 我笑而不...
    開封第一講書人閱讀 59,869評論 1 299
  • 正文 為了忘掉前任,我火速辦了婚禮彼绷,結(jié)果婚禮上巍佑,老公的妹妹穿的比我還像新娘。我一直安慰自己寄悯,他們只是感情好萤衰,可當(dāng)我...
    茶點故事閱讀 68,888評論 6 398
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著猜旬,像睡著了一般脆栋。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上洒擦,一...
    開封第一講書人閱讀 52,475評論 1 312
  • 那天椿争,我揣著相機與錄音,去河邊找鬼熟嫩。 笑死秦踪,一個胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播洋侨,決...
    沈念sama閱讀 41,010評論 3 422
  • 文/蒼蘭香墨 我猛地睜開眼舍扰,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了希坚?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 39,924評論 0 277
  • 序言:老撾萬榮一對情侶失蹤陵且,失蹤者是張志新(化名)和其女友劉穎裁僧,沒想到半個月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體慕购,經(jīng)...
    沈念sama閱讀 46,469評論 1 319
  • 正文 獨居荒郊野嶺守林人離奇死亡聊疲,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 38,552評論 3 342
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了沪悲。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片获洲。...
    茶點故事閱讀 40,680評論 1 353
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖殿如,靈堂內(nèi)的尸體忽然破棺而出贡珊,到底是詐尸還是另有隱情,我是刑警寧澤涉馁,帶...
    沈念sama閱讀 36,362評論 5 351
  • 正文 年R本政府宣布门岔,位于F島的核電站,受9級特大地震影響烤送,放射性物質(zhì)發(fā)生泄漏寒随。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 42,037評論 3 335
  • 文/蒙蒙 一帮坚、第九天 我趴在偏房一處隱蔽的房頂上張望妻往。 院中可真熱鬧,春花似錦试和、人聲如沸讯泣。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,519評論 0 25
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽判帮。三九已至,卻和暖如春溉箕,著一層夾襖步出監(jiān)牢的瞬間晦墙,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 33,621評論 1 274
  • 我被黑心中介騙來泰國打工肴茄, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留晌畅,地道東北人。 一個月前我還...
    沈念sama閱讀 49,099評論 3 378
  • 正文 我出身青樓寡痰,卻偏偏與公主長得像抗楔,于是被迫代替她去往敵國和親棋凳。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 45,691評論 2 361

推薦閱讀更多精彩內(nèi)容