rxjava 2.0开始多了一个Flowable,乍一看和Observable的方法差不多。但是当我调用create创建一个observable的时候发现多了一个差数
public static <T> Flowable<T> create(FlowableOnSubscribe<T> source, BackpressureStrategy mode) {
return RxJavaPlugins.onAssembly(new FlowableCreate<T>(source, mode));
}
BackpressureStrategy,背压策略 ,在异步环境下,当数据处理不够快时通过通知上游来控制流速的一种策略
public enum BackpressureStrategy {
/**
* OnNext events are written without any buffering or dropping.
* Downstream has to deal with any overflow.
* <p>Useful when one applies one of the custom-parameter onBackpressureXXX operators.
*/
MISSING,
/**
* Signals a MissingBackpressureException in case the downstream can't keep up.
*/
ERROR,
/**
* Buffers <em>all</em> onNext values until the downstream consumes it.
*/
BUFFER,
/**
* Drops the most recent onNext value if the downstream can't keep up.
*/
DROP,
/**
* Keeps only the latest onNext value, overwriting any previous value if the
* downstream can't keep up.
*/
LATEST
}
目前有这么多种背压策略。来看一下FlowableCreate是怎么根据背压策略来控制流速的。
首先创建一个Flowable查看输出值
Flowable
.create(new FlowableOnSubscribe<Integer>() {
@Override
public void subscribe(FlowableEmitter<Integer> emitter) throws Exception {
for (int i = 0; i < Integer.MAX_VALUE; i++) {
emitter.onNext(i);
Thread.sleep(20);
}
emitter.onComplete();
}
//随便定义一个策略
},BackpressureStrategy.MISSING)
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribe(new Consumer<Integer>() {
@Override
public void accept(Integer value) throws Exception {
//print value
}
});
如上的代码如果是Observable的话是打印0-max的,在Flowable下是怎么样呢。
在这里我是先查看源码在猜测输出值,看一下FlowableCreate.subscribeActual是怎么执行的。
public void subscribeActual(Subscriber<? super T> t) {
BaseEmitter<T> emitter;
switch (backpressure) {
case MISSING: {
emitter = new MissingEmitter<T>(t);
break;
}
case ERROR: {
emitter = new ErrorAsyncEmitter<T>(t);
break;
}
case DROP: {
emitter = new DropAsyncEmitter<T>(t);
break;
}
case LATEST: {
emitter = new LatestAsyncEmitter<T>(t);
break;
}
default: {
emitter = new BufferAsyncEmitter<T>(t, bufferSize());
break;
}
}
t.onSubscribe(emitter);
try {
source.subscribe(emitter);
} catch (Throwable ex) {
Exceptions.throwIfFatal(ex);
emitter.onError(ex);
}
}
MISSING
根据不同的策略创建不同的FlowableEmitter。接下来看一下MissingEmitter。
static final class MissingEmitter<T> extends BaseEmitter<T> {
private static final long serialVersionUID = 3776720187248809713L;
MissingEmitter(Subscriber<? super T> downstream) {
super(downstream);
}
@Override
public void onNext(T t) {
if (isCancelled()) {
return;
}
if (t != null) {
downstream.onNext(t);
} else {
onError(new NullPointerException("onNext called with null. Null values are generally not allowed in 2.x operators and sources."));
return;
}
for (;;) {
long r = get();
if (r == 0L || compareAndSet(r, r - 1)) {
return;
}
}
}
}
MissingEmitter继承了BaseEmitter,
abstract static class BaseEmitter<T>
extends AtomicLong
implements FlowableEmitter<T>, Subscription {
private static final long serialVersionUID = 7326289992464377023L;
final Subscriber<? super T> downstream;
//维持管理当前FlowableEmitters是否关闭订阅
final SequentialDisposable serial;
BaseEmitter(Subscriber<? super T> downstream) {
this.downstream = downstream;
this.serial = new SequentialDisposable();
}
@Override
public void onComplete() {
complete();
}
//没有关闭订阅 交给下游处理onComplete
protected void complete() {
if (isCancelled()) {
return;
}
try {
downstream.onComplete();
} finally {
serial.dispose();
}
}
@Override
public final void onError(Throwable e) {
if (!tryOnError(e)) {
RxJavaPlugins.onError(e);
}
}
@Override
public boolean tryOnError(Throwable e) {
return error(e);
}
//没有关闭订阅 交给下游处理onError
protected boolean error(Throwable e) {
if (e == null) {
e = new NullPointerException("onError called with null. Null values are generally not allowed in 2.x operators and sources.");
}
if (isCancelled()) {
return false;
}
try {
downstream.onError(e);
} finally {
serial.dispose();
}
return true;
}
//关闭订阅
@Override
public final void cancel() {
serial.dispose();
onUnsubscribed();
}
void onUnsubscribed() {
// default is no-op
}
@Override
public final boolean isCancelled() {
return serial.isDisposed();
}
@Override
public final void request(long n) {
//判断n是否大于0
if (SubscriptionHelper.validate(n)) {
BackpressureHelper.add(this, n);
onRequested();
}
}
void onRequested() {
// default is no-op
}
@Override
public final void setDisposable(Disposable d) {
serial.update(d);
}
@Override
public final void setCancellable(Cancellable c) {
setDisposable(new CancellableDisposable(c));
}
@Override
public final long requested() {
return get();
}
}
我们发现BaseEmitter实现了Subscription接口,里面有个request(int),就是他来实现流速的控制,表示可以处理多少个流。多次request调用是会累加的。
这里看一下request方法的具体实现:
由于BaseEmitter继承自AtomicLong,request流量的大小设置本质就是通过设置AtomicLong的值来实现。
首先调用SubscriptionHelper.validate(n)来判断是否大于0
是的话
public static long add(AtomicLong requested, long n) {
for (;;) {
//获取当前值
long r = requested.get();
if (r == Long.MAX_VALUE) {
return Long.MAX_VALUE;
}
//相加
long u = addCap(r, n);
//把相加的值赋值进去
if (requested.compareAndSet(r, u)) {
return r;
}
}
}
AtomicLong的值表示当前下游可以处理多少onNext输出。后面每当通知下游调用完一次onNext 就会调用BackpressureHelper.produced(this, 1);减1
BaseEmitter已经帮我实现了onError 和onComplete,所以他的继承类就只需要实现onNext
下面就看MissingEmitter具体是怎么实现的
static final class MissingEmitter<T> extends BaseEmitter<T> {
private static final long serialVersionUID = 3776720187248809713L;
MissingEmitter(Subscriber<? super T> downstream) {
super(downstream);
}
@Override
public void onNext(T t) {
//是否取消
if (isCancelled()) {
return;
}
//不为空就输出
if (t != null) {
downstream.onNext(t);
} else {
onError(new NullPointerException("onNext called with null. Null values are generally not allowed in 2.x operators and sources."));
return;
}
}
}
由上可知BackpressureStrategy.MISSING模式类似Observable 直接全部打印,所以上面的例子是打印从0-MAx。
ERROR
ErrorAsyncEmitter继承自NoOverflowBaseAsyncEmitter
static final class ErrorAsyncEmitter<T> extends NoOverflowBaseAsyncEmitter<T> {
private static final long serialVersionUID = 338953216916120960L;
ErrorAsyncEmitter(Subscriber<? super T> downstream) {
super(downstream);
}
@Override
void onOverflow() {
onError(new MissingBackpressureException("create: could not emit value due to lack of requests"));
}
}
abstract static class NoOverflowBaseAsyncEmitter<T> extends BaseEmitter<T> {
private static final long serialVersionUID = 4127754106204442833L;
NoOverflowBaseAsyncEmitter(Subscriber<? super T> downstream) {
super(downstream);
}
@Override
public final void onNext(T t) {
//是否取消订阅
if (isCancelled()) {
return;
}
if (t == null) {
onError(new NullPointerException("onNext called with null. Null values are generally not allowed in 2.x operators and sources."));
return;
}
//查看当前可处理的流量数量,是否允许下游处理
if (get() != 0) {
downstream.onNext(t);
//可处理的数量减1
BackpressureHelper.produced(this, 1);
} else {
//不允许 回调ErrorAsyncEmitter的onOverflow,抛出错误
onOverflow();
}
}
abstract void onOverflow();
}
可知ErrorAsyncEmitter是:当上游发送的数据大于下游可处理的数量时 就会抛出错误。
当初把代码改成下面这样
Flowable
.create(new FlowableOnSubscribe<Integer>() {
@Override
public void subscribe(FlowableEmitter<Integer> emitter) throws Exception {
for (int i = 0; i < Integer.MAX_VALUE; i++) {
emitter.onNext(i);
Thread.sleep(20);
}
emitter.onComplete();
}
//随便定义一个策略
},BackpressureStrategy.MISSING)
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribe(new FlowableSubscriber<Integer>() {
@Override
public void onSubscribe(Subscription s) {
s.request(5);
}
@Override
public void onNext(Integer value){
//print value
}
});
上面的代码会在打印五次之后抛出错误。
DROP
DropAsyncEmitter和ErrorAsyncEmitter一样继承于NoOverflowBaseAsyncEmitter
static final class DropAsyncEmitter<T> extends NoOverflowBaseAsyncEmitter<T> {
private static final long serialVersionUID = 8360058422307496563L;
DropAsyncEmitter(Subscriber<? super T> downstream) {
super(downstream);
}
@Override
void onOverflow() {
// nothing to do
}
}
但是他出错的时候不抛出错误,所以上游继续发送 但是下游没有接收到。
LATEST
LatestAsyncEmitter 是将上游最新的一个值保存起来,每次有新的next都会替换旧的值保存。
static final class LatestAsyncEmitter<T> extends BaseEmitter<T> {
private static final long serialVersionUID = 4023437720691792495L;
final AtomicReference<T> queue;
Throwable error;
volatile boolean done;
final AtomicInteger wip;
LatestAsyncEmitter(Subscriber<? super T> downstream) {
super(downstream);
this.queue = new AtomicReference<T>();
this.wip = new AtomicInteger();
}
@Override
public void onNext(T t) {
if (done || isCancelled()) {
return;
}
if (t == null) {
onError(new NullPointerException("onNext called with null. Null values are generally not allowed in 2.x operators and sources."));
return;
}
//每次有新的输出 保存起来
queue.set(t);
//
drain();
}
void drain() {
//drain()方法只能有一个在运行
if (wip.getAndIncrement() != 0) {
return;
}
int missed = 1;
//下游 比如FlowableSubscriber
final Subscriber<? super T> a = downstream;
//上游最新的值(FlowableEmitter.onNext(value)方法执行的值的)
final AtomicReference<T> q = queue;
for (;;) {
//获取当前下游可执行的流量数量,通过request(count)方法增加
long r = get();
long e = 0L;
//下游可以接收
while (e != r) {
//是否取消订阅
if (isCancelled()) {
q.lazySet(null);
return;
}
//没有执行onComplete,为false
boolean d = done;
//取出最新值,并且把变量设置为null
T o = q.getAndSet(null);
boolean empty = o == null;
if (d && empty) {
Throwable ex = error;
if (ex != null) {
error(ex);
} else {
complete();
}
return;
}
//最新值为null 说明数据已经被取出 跳出while循环
if (empty) {
break;
}
//调用下游的onNext
a.onNext(o);
e++;
}
//当前调用下游执行的次数 == 下游可执行的数量
if (e == r) {
if (isCancelled()) {
q.lazySet(null);
return;
}
boolean d = done;
boolean empty = q.get() == null;
if (d && empty) {
Throwable ex = error;
if (ex != null) {
error(ex);
} else {
complete();
}
return;
}
}
//如果当前有调用下游执行,就要减掉下游可执行数量
if (e != 0) {
BackpressureHelper.produced(this, e);
}
//跳出for循环
missed = wip.addAndGet(-missed);
if (missed == 0) {
break;
}
}
}
...
}
由此可知LatestAsyncEmitter主要思想就是 上游不断执行 ,在上游执行的那一段时间,如果下游不调用Subscription.request()获取,就永远没有收到onNext回调。
当上游执行完之后 会保持最后一个值,这时调用Subscription.request()也能获取到最后一个值
Subscription mSubscription;
Flowable
.create(new FlowableOnSubscribe<Integer>() {
@Override
public void subscribe(FlowableEmitter<Integer> emitter) throws Exception {
for (int i = 0; i < 5; i++) {
emitter.onNext(i);
Thread.sleep(20);
}
emitter.onComplete();
}
}, BackpressureStrategy.MISSING)
.subscribeOn(Schedulers.io())
.subscribe(new FlowableSubscriber<Integer>() {
@Override
public void onSubscribe(Subscription s) {
mSubscription = s;
}
@Override
public void onNext(Integer value){
//print value
}
});
因此当几秒钟之后我调用mSubscription.request(5),仍然能在onNext获取到值"4".
BUFFER
BufferAsyncEmitter的代码结构类似LatestAsyncEmitter,唯一的不同是LatestAsyncEmitter只保存上游最后一个值,BufferAsyncEmitter是使用一个队列保存上游的所有输出。
mSubscription.request的时候是从队列获取。
因此下面的代码当我多次调用mSubscription.request(5)获取的时候
第一次是 0-4 第二次是5-9 第三次是10-14 …
Subscription mSubscription;
Flowable
.create(new FlowableOnSubscribe<Integer>() {
@Override
public void subscribe(FlowableEmitter<Integer> emitter) throws Exception {
for (int i = 0; i < Integer.MAX_VALUE; i++) {
emitter.onNext(i);
Thread.sleep(20);
}
emitter.onComplete();
}
}, BackpressureStrategy.MISSING)
.subscribeOn(Schedulers.io())
.subscribe(new FlowableSubscriber<Integer>() {
@Override
public void onSubscribe(Subscription s) {
mSubscription = s;
}
@Override
public void onNext(Integer value){
//print value
}
});