https://github.com/ReactiveX/RxJava/wiki/Backpressure-(2.0)
1.前言
1.在Rxjava1.x中不存在背壓模式
2.在RxJava2.x中產生了了背壓模式
1.什麼是背壓模式
背壓模式主要是爲了解決上游發送大量的事件,下游處理不過來的情況,使用Flowable來操作。相比較Observable多了背壓策略。
背壓涉及到數據緩衝池,緩衝池大小爲128
2.背壓的使用
因爲使用背壓模式就不得不使用到背壓的模式,所以下面根據提供的幾種背壓模式來說明,背壓模式採用Flowable創建被觀察者,
對應的觀察者應該爲Subscriber,也可以使用快捷簡單的Consumer
和前面講到的Observable對比如下
Observable -------> Observer
Flowable -------> Subscriber
2.1 BackpressureStrategy.ERROR
說明
上游發送大量數據,下游處理不過來(發生了阻塞,常常出現在異步操作裏面),放入緩存池(128大小) ,如果池子滿了,就會拋出異常
例子
Flowable.create(new FlowableOnSubscribe<String>() {
@Override
public void subscribe(FlowableEmitter<String> emitter) throws Exception {
for (int i = 0; i < 200; i++) { //
emitter.onNext("===> " + i);
}
emitter.onComplete();
}
}, BackpressureStrategy.ERROR)
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribe(new Subscriber<String>() {
@Override
public void onSubscribe(Subscription s) {
s.request(200); //請求發射的數據 如果小於上游發射的數據,則還有部分數據不能正常發射則會拋出異常
}
@Override
public void onNext(String s) {
try {
Thread.sleep(1);
} catch (InterruptedException e) {
e.printStackTrace();
}
Log.i(TAG, "onNext: " + s);
}
@Override
public void onError(Throwable t) {
Log.i(TAG, "onError: " + t);
}
@Override
public void onComplete() {
Log.i(TAG, "onComplete: ");
}
});
輸出1 (由於在上面我們說明了,緩衝池大小爲128,在此例子中,我們不間斷的發射200條數據,採用異步的方式,下游會休眠1毫秒,這樣就會導致,上游不斷的發射數據,下游處理不過來,會往緩衝池存儲,緩衝池滿了以後,就會拋出異常。)
1572315942.919 I/MainActivity: onNext: ===> 0
1572315942.920 I/MainActivity: onNext: ===> 1
1572315942.921 I/MainActivity: onNext: ===> 2
1572315942.923 I/MainActivity: onNext: ===> 3
1572315942.924 I/MainActivity: onNext: ===> 4
1572315942.925 I/MainActivity: onNext: ===> 5
1572315942.927 I/MainActivity: onNext: ===> 6
1572315942.928 I/MainActivity: onNext: ===> 7
1572315942.929 I/MainActivity: onNext: ===> 8
1572315942.930 I/MainActivity: onNext: ===> 9
1572315942.932 I/MainActivity: onNext: ===> 10
1572315942.933 I/MainActivity: onNext: ===> 11
1572315942.934 I/MainActivity: onError: io.reactivex.exceptions.MissingBackpressureException: create: could not emit value due to lack of requests
案例2 下面我們修改一下上面的數據,再次驗證
Flowable.create(new FlowableOnSubscribe<String>() {
@Override
public void subscribe(FlowableEmitter<String> emitter) throws Exception {
for (int i = 0; i < 200; i++) {
emitter.onNext("===> " + i);
}
emitter.onComplete();
}
}, BackpressureStrategy.ERROR)
// .subscribeOn(Schedulers.io())
// .observeOn(AndroidSchedulers.mainThread())
.subscribe(new Subscriber<String>() {
@Override
public void onSubscribe(Subscription s) {
s.request(200);
}
@Override
public void onNext(String s) {
// try {
// Thread.sleep(1);
// } catch (InterruptedException e) {
// e.printStackTrace();
// }
Log.i(TAG, "onNext: " + s);
}
@Override
public void onError(Throwable t) {
Log.i(TAG, "onError: " + t);
}
@Override
public void onComplete() {
Log.i(TAG, "onComplete: ");
}
});
這裏我們註釋掉了線程的切換,讓程序在一個線程裏面運行,註釋掉了線程休眠1毫秒的操作,這個時候上游發射的數據,下游能夠及時的處理,不會出現阻塞的情況。輸出結果如下
1572316741.677 I/MainActivity: onNext: ===> 0
1572316741.677 I/MainActivity: onNext: ===> 1
1572316741.677 I/MainActivity: onNext: ===> 2
(省略...太長了)
1572316741.683 I/MainActivity: onNext: ===> 197
1572316741.683 I/MainActivity: onNext: ===> 198
1572316741.683 I/MainActivity: onNext: ===> 199
1572316741.683 I/MainActivity: onComplete:
2.2 BackpressureStrategy.BUFFER
說明
上游發送大量數據,下游處理不過來 ,等待下游接收事件處理
例子 (還是採用上面的第一個例子,只是背壓模式改成了Buffer)
Flowable.create(new FlowableOnSubscribe<String>() {
@Override
public void subscribe(FlowableEmitter<String> emitter) throws Exception {
for (int i = 0; i < 200; i++) {
emitter.onNext("===> " + i);
}
emitter.onComplete();
}
}, BackpressureStrategy.BUFFER)
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribe(new Subscriber<String>() {
@Override
public void onSubscribe(Subscription s) {
s.request(200);
}
@Override
public void onNext(String s) {
try {
Thread.sleep(1);
} catch (InterruptedException e) {
e.printStackTrace();
}
Log.i(TAG, "onNext: " + s);
}
@Override
public void onError(Throwable t) {
Log.i(TAG, "onError: " + t);
}
@Override
public void onComplete() {
Log.i(TAG, "onComplete: ");
}
});
輸出 (可以看到改成Buffer以後,上游處理不過來的時候會等待下去,直到全部處理完成)
1572317529.486 I/MainActivity: onNext: ===> 0
1572317529.487 I/MainActivity: onNext: ===> 1
1572317529.488 I/MainActivity: onNext: ===> 2
(部分省略。。。。)
1572317529.770 I/MainActivity: onNext: ===> 195
1572317529.771 I/MainActivity: onNext: ===> 196
1572317529.773 I/MainActivity: onNext: ===> 197
1572317529.774 I/MainActivity: onNext: ===> 198
1572317529.775 I/MainActivity: onNext: ===> 199
1572317529.776 I/MainActivity: onComplete:
2.3 BackpressureStrategy.DROP(不常用)
說明
上游發送大量數據,下游處理不過來 放入緩存池 ,如果池子滿了,就會把後面的數據丟棄
例子
Flowable.create(new FlowableOnSubscribe<String>() {
@Override
public void subscribe(FlowableEmitter<String> emitter) throws Exception {
for (int i = 0; i < 200; i++) {
emitter.onNext("===> " + i);
}
emitter.onComplete();
}
}, BackpressureStrategy.DROP)
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribe(new Subscriber<String>() {
@Override
public void onSubscribe(Subscription s) {
s.request(200);
}
@Override
public void onNext(String s) {
try {
Thread.sleep(1);
} catch (InterruptedException e) {
e.printStackTrace();
}
Log.i(TAG, "onNext: " + s);
}
@Override
public void onError(Throwable t) {
Log.i(TAG, "onError: " + t);
}
@Override
public void onComplete() {
Log.i(TAG, "onComplete: ");
}
});
輸出
1572318474.529 I/MainActivity: onNext: ===> 0
1572318474.531 I/MainActivity: onNext: ===> 1
(省略。。。。)
1572318474.699 I/MainActivity: onNext: ===> 125
1572318474.702 I/MainActivity: onNext: ===> 126
1572318474.703 I/MainActivity: onNext: ===> 127 (緩衝池滿了就會丟棄掉後面的數據)
1572318474.704 I/MainActivity: onComplete:
2.4 BackpressureStrategy.LATEST(不常用)
說明
註釋說明:Keeps only the latest onNext value, overwriting any previous value if the downstream can't keep up.
上游發送大量數據,下游處理不過來 ,只存儲128條數據,最後還會發送最後一條數據
例子
Flowable.create(new FlowableOnSubscribe<String>() {
@Override
public void subscribe(FlowableEmitter<String> emitter) throws Exception {
for (int i = 0; i < 150; i++) {
emitter.onNext("===> " + i);
}
emitter.onComplete();
}
}, BackpressureStrategy.LATEST)
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribe(new Subscriber<String>() {
@Override
public void onSubscribe(Subscription s) {
s.request(150);
}
@Override
public void onNext(String s) {
try {
Thread.sleep(10);
} catch (InterruptedException e) {
e.printStackTrace();
}
Log.i(TAG, "onNext: " + s);
}
@Override
public void onError(Throwable t) {
Log.i(TAG, "onError: " + t);
}
@Override
public void onComplete() {
Log.i(TAG, "onComplete: ");
}
});
輸出(可以看到在最後輸出了128條數據以後,最後還發送了一條149的數據,149在發送的數據裏面就是最後一條也是最新的一條數據,也會被打印出來)
1572330316.528 I/MainActivity: onNext: ===> 0
1572330316.540 I/MainActivity: onNext: ===> 1
(省略。。。。)
1572330317.889 I/MainActivity: onNext: ===> 126
1572330317.900 I/MainActivity: onNext: ===> 127
1572330317.910 I/MainActivity: onNext: ===> 149
3.結尾
//背壓四種模式 (緩存池128)
//1.BackpressureStrategy.ERROR //上游發送大量數據,下游處理不過來,放入緩存池 ,如果池子滿了,就會拋出異常
//2.BackpressureStrategy.BUFFER //上游發送大量數據,下游處理不過來 ,等待下游接收事件處理
//3.BackpressureStrategy.DROP(不常用) //上游發送大量數據,下游處理不過來 放入緩存池 ,如果池子滿了,就會把後面的數據丟棄
//4.BackpressureStrategy.LATEST(不常用) //上游發送大量數據,下游處理不過來 ,只存儲128條數據,最後還會發送最後一條數據
通過 Subscription.request(n) 方法,請求發射的數量