本文章主要是对RxJava2的FlatMap和ConcatMap这两个操作符进行源码分析,并且对其相关并发编程进行分析,在阅读之前,可以先阅读以下文章:
本文章用的RxJava和RxAndroid版本如下:
implementation 'io.reactivex.rxjava2:rxjava:2.2.6'
implementation 'io.reactivex.rxjava2:rxandroid:2.1.1'
FlatMap
FlatMap操作符可以将一个发射数据的Observable转变为多个Observables,然后将这些发射的数据合并进一个单独的Observable,发射的数据不保证有序。
我们先写段示例代码,为了方便理解,在调用FlatMap方法的时候,我就不用上Lambda和链式调用了,代码如下:
Observable.create((ObservableOnSubscribe<String>) emitter -> {
emitter.onNext("Tan:");
emitter.onNext("Jia:");
emitter.onNext("Jun:");
emitter.onComplete();
})
.flatMap(new Function<String, ObservableSource<String>>() {
@Override
public ObservableSource<String> apply(String s) {
List<String> list = new ArrayList<>();
for (int i = 0; i < 3; i++) {
list.add(s + i);
}
return Observable.fromIterable(list);
}
})
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribe(new Observer<String>() {
@Override
public void onSubscribe(Disposable d) {
// no implementation
}
@Override
public void onNext(String s) {
Log.i("TanJiaJun", s);
}
@Override
public void onError(Throwable e) {
// no implementation
}
@Override
public void onComplete() {
// no implementation
}
});
Log如下:
源码分析
我们看下flatMap方法,分析可知,会依次调用以下方法,代码如下:
@CheckReturnValue
@SchedulerSupport(SchedulerSupport.NONE)
public final <R> Observable<R> flatMap(Function<? super T, ? extends ObservableSource<? extends R>> mapper) {
// 注意:参数delayErrors传入的是false
return flatMap(mapper, false);
}
@CheckReturnValue
@SchedulerSupport(SchedulerSupport.NONE)
public final <R> Observable<R> flatMap(Function<? super T, ? extends ObservableSource<? extends R>> mapper, boolean delayErrors) {
// 注意:参数maxConcurrency传入的是Integer.MAX_VALUE
return flatMap(mapper, delayErrors, Integer.MAX_VALUE);
}
@CheckReturnValue
@SchedulerSupport(SchedulerSupport.NONE)
public final <R> Observable<R> flatMap(Function<? super T, ? extends ObservableSource<? extends R>> mapper, boolean delayErrors, int maxConcurrency) {
// bufferSize是指数据缓冲区的大小,与背压(Backpressure)有关
return flatMap(mapper, delayErrors, maxConcurrency, bufferSize());
}
@CheckReturnValue
@SchedulerSupport(SchedulerSupport.NONE)
public final <R> Observable<R> flatMap(Function<? super T, ? extends ObservableSource<? extends R>> mapper, boolean delayErrors, int maxConcurrency, int bufferSize) {
ObjectHelper.requireNonNull(mapper, "mapper is null");
ObjectHelper.verifyPositive(maxConcurrency, "maxConcurrency");
ObjectHelper.verifyPositive(bufferSize, "bufferSize");
// 这里有个判断,判断this是不是ScalarCallable的实现类,详细解释请看下面
if (this instanceof ScalarCallable) {
@SuppressWarnings("unchecked")
T v = ((ScalarCallable<T>)this).call();
if (v == null) {
return empty();
}
return ObservableScalarXMap.scalarXMap(v, mapper);
}
// 如果不是ScalarCallable的实现类就会调用以下方法
return RxJavaPlugins.onAssembly(new ObservableFlatMap<T, R>(this, mapper, delayErrors, maxConcurrency, bufferSize));
}
bufferSize()是数据缓冲区的大小,默认是128,可从以下代码得知:
// Observable.java
public static int bufferSize() {
return Flowable.bufferSize();
}
// Flowable.java
public static int bufferSize() {
return BUFFER_SIZE;
}
// Flowable.java
/** The default buffer size. */
static final int BUFFER_SIZE;
static {
BUFFER_SIZE = Math.max(1, Integer.getInteger("rx2.buffer-size", 128));
}
ScalarCallable是一个接口,它的实现类有6个:FlowableEmpty、FlowableJust、MaybeEmpty、MaybeJust、ObservableEmpty、ObservableJust,分别对应这6个方法:Flowable.empty()、Flowable.just(T item)、Maybe.empty()、Maybe.just(T item)、Observable.empty()、Observable.just(T item)。
根据前几篇文章的经验可知,我们只要看ObservableFlatMap这个类就行了,代码如下:
// ObservableFlatMap.java
public ObservableFlatMap(ObservableSource<T> source,
Function<? super T, ? extends ObservableSource<? extends U>> mapper,
boolean delayErrors, int maxConcurrency, int bufferSize) {
super(source);
this.mapper = mapper;
this.delayErrors = delayErrors;
this.maxConcurrency = maxConcurrency;
this.bufferSize = bufferSize;
}
@Override
public void subscribeActual(Observer<? super U> t) {
if (ObservableScalarXMap.tryScalarXMapSubscribe(source, t, mapper)) {
return;
}
source.subscribe(new MergeObserver<T, U>(t, mapper, delayErrors, maxConcurrency, bufferSize));
}
我们也像前几篇文章那样,先看下subscribeActual方法,这里会先调用ObservableScalarXMap.tryScalarXMapSubscribe方法,如果是true的话就return,这个方法中会判断source是不是Callable的实现类,如果是的话就会委托ObservableScalarXMap来发射事件,然后返回true,否则返回false,上面说的ScalarCallable接口就是继承Callable接口,所以我们主要是看下面的逻辑,调用了source的subscribe方法,并且传入new出来的MergeObserver,我们来看下MergeObserver这个类,要注意的点我都写上注释了,代码如下:
// ObservableFlatMap.java
// MergeObserver继承AtomicInteger
static final class MergeObserver<T, U> extends AtomicInteger implements Disposable, Observer<T> {
private static final long serialVersionUID = -2117620485640801370L;
final Observer<? super U> downstream;
final Function<? super T, ? extends ObservableSource<? extends U>> mapper;
final boolean delayErrors;
final int maxConcurrency;
final int bufferSize;
volatile SimplePlainQueue<U> queue;
volatile boolean done;
final AtomicThrowable errors = new AtomicThrowable();
volatile boolean cancelled;
// 存放InnerObserver的数组
final AtomicReference<InnerObserver<?, ?>[]> observers;
static final InnerObserver<?, ?>[] EMPTY = new InnerObserver<?, ?>[0];
static final InnerObserver<?, ?>[] CANCELLED = new InnerObserver<?, ?>[0];
Disposable upstream;
long uniqueId;
long lastId;
int lastIndex;
Queue<ObservableSource<? extends U>> sources;
int wip;
MergeObserver(Observer<? super U> actual, Function<? super T, ? extends ObservableSource<? extends U>> mapper,
boolean delayErrors, int maxConcurrency, int bufferSize) {
this.downstream = actual;
// mapper是Function接口的实现类
this.mapper = mapper;
this.delayErrors = delayErrors;
this.maxConcurrency = maxConcurrency;
this.bufferSize = bufferSize;
// 根据上面的代码可知,传入的Integer.MAX_VALUE,所以这段逻辑不会
if (maxConcurrency != Integer.MAX_VALUE) {
sources = new ArrayDeque<ObservableSource<? extends U>>(maxConcurrency);
}
// 创建一个InnerObserver数组的原子引用
this.observers = new AtomicReference<InnerObserver<?, ?>[]>(EMPTY);
}
@Override
public void onSubscribe(Disposable d) {
if (DisposableHelper.validate(this.upstream, d)) {
this.upstream = d;
downstream.onSubscribe(this);
}
}
@Override
public void onNext(T t) {
// safeguard against misbehaving sources
if (done) {
return;
}
ObservableSource<? extends U> p;
try {
// 调用mapper的apply方法
p = ObjectHelper.requireNonNull(mapper.apply(t), "The mapper returned a null ObservableSource");
} catch (Throwable e) {
Exceptions.throwIfFatal(e);
upstream.dispose();
onError(e);
return;
}
// 在上面也分析过了,传入的Integer.MAX_VALUE,所以这段逻辑不会执行
if (maxConcurrency != Integer.MAX_VALUE) {
synchronized (this) {
if (wip == maxConcurrency) {
sources.offer(p);
return;
}
wip++;
}
}
subscribeInner(p);
}
@SuppressWarnings("unchecked")
void subscribeInner(ObservableSource<? extends U> p) {
// 一个死循环
for (;;) {
// 判断p是不是Callable接口的实现类,上面分析过,这里不再赘述
if (p instanceof Callable) {
if (tryEmitScalar(((Callable<