文章导航
背压
当上下游在不同的线程中,通过Observable发射,处理,响应数据流时,如果上游发射数据的速度快于下游接收处理数据的速度,这样对于那些没来得及处理的数据就会造成积压,这些数据既不会丢失,也不会被垃圾回收机制回收,而是存放在一个异步缓存池中,如果缓存池中的数据一直得不到处理,越积越多,最后就会造成内存溢出,这便是响应式编程中的背压(backpressure)问题。
- 在订阅的时候如果使用FlowableSubscriber,那么需要通过s.request(Long.MAX_VALUE)去主动请求上游的数据项。如果遇到背压报错的时候,FlowableSubscriber默认已经将错误try-catch,并通过onError()进行回调,程序并不会崩溃;
- 在订阅的时候如果使用Consumer,那么不需要主动去请求上游数据,默认已经调用了s.request(Long.MAX_VALUE)。如果遇到背压报错、且对Throwable的Consumer没有new出来,则程序直接崩溃;
- 背压策略的上游的默认缓存池是128。
RxJava基本响应类型
1.Observable
Observable是最基本的响应类型,但不支持背压,基本上适用大多数的应用场景
public static void observable() {
//创建被观察者
Observable.create(new ObservableOnSubscribe<String>() {
@Override
//默认在主线程里执行该方法
public void subscribe(@NonNull ObservableEmitter<String> e) throws Exception {
e.onNext("1");
e.onNext("2");
e.onNext("3");
e.onNext("4");
e.onComplete();
}
})
//将被观察者切换到子线程
.subscribeOn(Schedulers.io())
//将观察者切换到主线程 需要在Android环境下运行
//.observeOn(AndroidSchedulers.mainThread())
//创建观察者并订阅
.subscribe(new Observer<String>() {
@Override
public void onSubscribe(Disposable d) {
}
@Override
public void onNext(String s) {
System.out.println("onNext=" + s);
}
@Override
public void onError(Throwable e) {
System.out.println("onError=" + e.getMessage());
}
@Override
public void onComplete() {
System.out.println("onComplete");
}
});
}
2.Flowable
Flowable和Observable的使用基本相同,只不过Observable不支持背压,而Flowable支持背压。但需要注意的是,使用Flowable的时候,必须调用Subscription的requsest方法请求,不然上游是不会发射数据的。
public static void flowable() {
//创建被观察者
Flowable.create(new FlowableOnSubscribe<String>() {
@Override
public void subscribe(FlowableEmitter<String> e) throws Exception {
e.onNext("1");
e.onNext("2");
e.onNext("3");
e.onNext("4");
e.onComplete();
}
}, BackpressureStrategy.MISSING)
//将被观察者切换到子线程
.subscribeOn(Schedulers.io())
//将观察者切换到主线程 需要在Android环境下运行
//.observeOn(AndroidSchedulers.mainThread())
//创建观察者并订阅
.subscribe(new Subscriber<String>() {
@Override
public void onSubscribe(Subscription s) {
s.request(3);
}
@Override
public void onNext(String s) {
System.out.println("onNext=" + s);
}
@Override
public void onError(Throwable t) {
System.out.println("onError=" + t.getMessage());
}
@Override
public void onComplete() {
System.out.println("onComplete");
}
});
}
输出
onNext=1
onNext=2
onNext=3
背压策略
- MISSING: OnNext事件没有任何缓存和丢弃,下游要处理任何溢出,上游发射的数据未得到处理,就会缓存起来,当缓存容量达到128时,再增加一个未处理的数据项,就会抛出MissingBackpressureException,且带有队列已经满了的友好提示。
- ERROR: 上游发射的数据未得到处理,就会缓存起来,当缓存容量达到128时,再增加一个未处理的数据项,就会抛出MissingBackpressureException。
- BUFFER: 上游不断的发出onNext请求,直到下游处理完,上游发射的数据项的缓存池是无限大的,程序也不会抛出错误,但是要注意程序OOM的现象,因为缓存越大,占用的内存就越多。
- DROP: 超过缓存区大小(128)的数据项都会被丢弃。
- LATEST: LATEST与Drop策略一样,如果超过缓存池容量大小的数据项都会被丢弃。不同的是,不管缓存池的状态如何,LATEST都会将最后一条数据强行放入缓存池中。
3.Single
Single只发射一个元素,发射onSuccess或onError方法,所以没有complete方法,不像Observable或者Flowable,数据发射完成之后,需要调用complete告诉下游已经完成。
public static void single() {
//创建被观察者
Single.create(new SingleOnSubscribe<String>() {
@Override
public void subscribe(SingleEmitter<String> e) throws Exception {
e.onSuccess("success");
}
})
//将被观察者切换到子线程
.subscribeOn(Schedulers.io())
//将观察者切换到主线程 需要在Android环境下运行
//.observeOn(AndroidSchedulers.mainThread())
//创建观察者并订阅
.subscribe(new SingleObserver<String>() {
@Override
public void onSubscribe(Disposable d) {
}
@Override
public void onSuccess(String s) {
System.out.println("onSuccess=" + s);
}
@Override
public void onError(Throwable e) {
System.out.println("onError=" + e.getMessage());
}
});
}
4.Completable
Completable不会发射数据,只会给下游发送一个信号。回调onComplete或onError方法。
public static void completable() {
//创建被观察者
Completable.create(new CompletableOnSubscribe() {
@Override
public void subscribe(CompletableEmitter e) throws Exception {
e.onComplete();
}
})
//将被观察者切换到子线程
.subscribeOn(Schedulers.io())
//将观察者切换到主线程 需要在Android环境下运行
//.observeOn(AndroidSchedulers.mainThread())
//创建观察者并订阅
.subscribe(new CompletableObserver() {
@Override
public void onSubscribe(Disposable d) {
}
@Override
public void onComplete() {
System.out.println("onComplete");
}
@Override
public void onError(Throwable e) {
System.out.println("onError=" + e.getMessage());
}
});
}
5.Maybe
Maybe是Single和Completable的结合,需要注意的是onSuccess和onComplete方法只会执行其中一个,这不同于Observable和Flowable最后是以onComplete()结尾。
public static void maybe() {
//创建被观察者
Maybe.create(new MaybeOnSubscribe<String>() {
@Override
public void subscribe(MaybeEmitter<String> e) throws Exception {
e.onSuccess("success");
e.onComplete();
}
})
//将被观察者切换到子线程
.subscribeOn(Schedulers.io())
//将观察者切换到主线程 需要在Android环境下运行
//.observeOn(AndroidSchedulers.mainThread())
//创建观察者并订阅
.subscribe(new MaybeObserver<String>() {
@Override
public void onSubscribe(Disposable d) {
}
@Override
public void onSuccess(String s) {
System.out.println("onSuccess=" + s);
}
@Override
public void onError(Throwable e) {
System.out.println("onError=" + e.getMessage());
}
@Override
public void onComplete() {
System.out.println("onComplete");
}
});
}
小结
- Observable:最基本的响应类型,不支持背压
- Flowable:最基本的响应类型,支持背压
- Single:只发射一个数据的响应类型
- Completable:只发射一个信号的响应类型
- Maybe:Single和Completable的结合体