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) 方法,请求发射的数量