关于Observable的源码解析可以看Rxjava2 Observable源码浅析
关于Flowable的源码解析可以看RxJava2 Flowable源码浅析
前言
关于suject可能在Android用的不多,一般来说subject都是用于跨组件的通信工具,可选库可以选RxBus或EventBus。
官方的解释,Subject在同一时间内,既可以作为Observable,也可以作为Observer,在继承实现的关系上也是可以看出的。
//既是数据源,也是数据订阅者
public abstract class Subject<T> extends Observable<T> implements Observer<T>
在RxJava2.x中,官方一共为我们提供了以下几种Subject:
- ReplaySubject (释放接收到的所有数据)
- BehaviorSubject (释放订阅前最后一个数据和订阅后接收到的所有数据)
- PublishSubject (释放订阅后接收到的数据)
- AsyncSubject (仅释放接收到的最后一个数据)
- SerializedSubject(串行Subject)
- UnicastSubject (仅支持订阅一次的Subject)
ReplaySubject
public final class ReplaySubject<T> extends Subject<T> {
//数据缓存区
final ReplayBuffer<T> buffer;
//订阅者列表
final AtomicReference<ReplayDisposable<T>[]> observers;
@SuppressWarnings("rawtypes")
static final ReplayDisposable[] EMPTY = new ReplayDisposable[0];//用于表示无订阅者
@SuppressWarnings("rawtypes")
static final ReplayDisposable[] TERMINATED = new ReplayDisposable[0];//用于表示结束
//标记是否已经完成(调用过onComplete/onError)
boolean done;
public static <T> ReplaySubject<T> create() {
//buffer为UnboundedReplayBuffer
return new ReplaySubject<T>(new UnboundedReplayBuffer<T>(16));
}
//继承于Observable,subscribe最终调用到该方法重新下发数据
@Override
protected void subscribeActual(Observer<? super T> observer) {
ReplayDisposable<T> rs = new ReplayDisposable<T>(observer, this);
observer.onSubscribe(rs);
if (!rs.cancelled) {
if (add(rs)) {
if (rs.cancelled) {
remove(rs);
return;
}
}
//通过buffer重发数据
buffer.replay(rs);
}
}
@Override
public void onNext(T t) {
ObjectHelper.requireNonNull(t, "onNext called with null. Null values are generally not allowed in 2.x operators and sources.");
if (done) {
return;
}
ReplayBuffer<T> b = buffer;
b.add(t);//将数据插入buffer
for (ReplayDisposable<T> rs : observers.get()) {
b.replay(rs);//调用replay
}
}
//ReplayDisposable继承于AtomicInteger,用于标识onNext下发(buffer#replay)过几次
static final class ReplayDisposable<T> extends AtomicInteger implements Disposable {
private static final long serialVersionUID = 466549804534799122L;
final Observer<? super T> downstream;
final ReplaySubject<T> state;
Object index;//用于记录对应已经下发过buff数据的最后index,避免数据重复下发
volatile boolean cancelled;
ReplayDisposable(Observer<? super T> actual, ReplaySubject<T> state) {
this.downstream = actual;
this.state = state;
}
@Override
public void dispose() {
if (!cancelled) {
cancelled = true;
state.remove(this);
}
}
@Override
public boolean isDisposed() {
return cancelled;
}
}
static final class UnboundedReplayBuffer<T>
extends AtomicReference<Object>
implements ReplayBuffer<T> {
private static final long serialVersionUID = -733876083048047795L;
final List<Object> buffer;
volatile boolean done;
volatile int size;
.....
@Override
@SuppressWarnings("unchecked")
public void replay(ReplayDisposable<T> rs) {
if (rs.getAndIncrement() != 0) {//已经被replay了
return;
}
int missed = 1;
final List<Object> b = buffer;
final Observer<? super T> a = rs.downstream;
//获取已下发数据在缓存中的index
Integer indexObject = (Integer)rs.index;
int index;
if (indexObject != null) {
index = indexObject;
} else {
index = 0;
rs.index = 0;
}
for (;;) {
if (rs.cancelled) {
rs.index = null;
return;
}
int s = size;
while (s != index) {
if (rs.cancelled) {
rs.index = null;
return;
}
//获取index对应数据
Object o = b.get(index);
if (done) {//已调用onComplete/onError
if (index + 1 == s) {
s = size;
if (index + 1 == s) {
if (NotificationLite.isComplete(o)) {
a.onComplete();
} else {
a.onError(NotificationLite.getError(o));
}
rs.index = null;
rs.cancelled = true;
return;
}
}
}
a.onNext((T)o);//下发
index++;//index自增
}
if (index != size) {
continue;
}
//更新index
rs.index = index;
//参考Flowable/Observable,主要用于处理多次调用onNext
missed = rs.addAndGet(-missed);
if (missed == 0) {
break;
}
}
}
...
}
}
ReplaySubject看着代码很长,但逻辑很简单,主要就是通过buffer(ArrayList)缓存数据,在订阅时重新下发。重要代码已经加上注释。
PublishSubject
public final class PublishSubject<T> extends Subject<T> {
static final PublishDisposable[] TERMINATED = new PublishDisposable[0];
static final PublishDisposable[] EMPTY = new PublishDisposable[0];
final AtomicReference<PublishDisposable<T>[]> subscribers;
Throwable error;
@CheckReturnValue
@NonNull
public static <T> PublishSubject<T> create() {
return new PublishSubject<T>();
}
@SuppressWarnings("unchecked")
PublishSubject() {
subscribers = new AtomicReference<PublishDisposable<T>[]>(EMPTY);
}
@Override
protected void subscribeActual(Observer<? super T> t) {
PublishDisposable<T> ps = new PublishDisposable<T>(t, this);
t.onSubscribe(ps);
if (add(ps)) {
// if cancellation happened while a successful add, the remove() didn't work
// so we need to do it again
if (ps.isDisposed()) {
remove(ps);
}
} else {
Throwable ex = error;
if (ex != null) {
t.onError(ex);
} else {
t.onComplete();
}
}
}
@Override
public void onNext(T t) {
ObjectHelper.requireNonNull(t, "onNext called with null. Null values are generally not allowed in 2.x operators and sources.");
for (PublishDisposable<T> pd : subscribers.get()) {
pd.onNext(t);
}
}
static final class PublishDisposable<T> extends AtomicBoolean implements Disposable {
PublishDisposable(Observer<? super T> actual, PublishSubject<T> parent) {
this.downstream = actual;
this.parent = parent;
}
public void onNext(T t) {
if (!get()) {//dispose()会将自身设为true
downstream.onNext(t);
}
}
}
}
emmm...PublishSubject是最简单de,因为没有缓存机制,只要直接将onNext的数据下发到PublishDisposable即可。
BehaviorSubject
public final class BehaviorSubject<T> extends Subject<T> {
private static final Object[] EMPTY_ARRAY = new Object[0];
final AtomicReference<Object> value;
final AtomicReference<BehaviorDisposable<T>[]> subscribers;
static final BehaviorDisposable[] EMPTY = new BehaviorDisposable[0];
static final BehaviorDisposable[] TERMINATED = new BehaviorDisposable[0];
final ReadWriteLock lock;
//读写锁,数据源和下发数据到订阅者明显是生产者-消费者模式
final Lock readLock;
final Lock writeLock;
final AtomicReference<Throwable> terminalEvent;
long index;//用于记录当前下发的次数
public static <T> BehaviorSubject<T> create() {
return new BehaviorSubject<T>();
}
BehaviorSubject() {
this.lock = new ReentrantReadWriteLock();
this.readLock = lock.readLock();
this.writeLock = lock.writeLock();
this.subscribers = new AtomicReference<BehaviorDisposable<T>[]>(EMPTY);
this.value = new AtomicReference<Object>();
this.terminalEvent = new AtomicReference<Throwable>();
}
@Override
protected void subscribeActual(Observer<? super T> observer) {
BehaviorDisposable<T> bs = new BehaviorDisposable<T>(observer, this);
observer.onSubscribe(bs);//开始订阅
if (add(bs)) {//加入订阅队列
if (bs.cancelled) {
remove(bs);
} else {
bs.emitFirst();//下发最近的一次数据
}
} else {
Throwable ex = terminalEvent.get();
if (ex == ExceptionHelper.TERMINATED) {
observer.onComplete();
} else {
observer.onError(ex);
}
}
}
@Override
public void onNext(T t) {
ObjectHelper.requireNonNull(t, "onNext called with null. Null values are generally not allowed in 2.x operators and sources.");
if (terminalEvent.get() != null) {
return;
}
Object o = NotificationLite.next(t);
setCurrent(o);
for (BehaviorDisposable<T> bs : subscribers.get()) {
bs.emitNext(o, index);//最终通过test方法下发
}
}
@Override
public void onError(Throwable t) {
ObjectHelper.requireNonNull(t, "onError called with null. Null values are generally not allowed in 2.x operators and sources.");
if (!terminalEvent.compareAndSet(null, t)) {
RxJavaPlugins.onError(t);
return;
}
Object o = NotificationLite.error(t);
for (BehaviorDisposable<T> bs : terminate(o)) {
bs.emitNext(o, index);//最终通过test方法下发
}
}
@Override
public void onComplete() {
if (!terminalEvent.compareAndSet(null, ExceptionHelper.TERMINATED)) {
return;
}
Object o = NotificationLite.complete();
for (BehaviorDisposable<T> bs : terminate(o)) {
bs.emitNext(o, index); // relaxed read okay since this is the only mutator thread
}
}
void setCurrent(Object o) {//多线程OnNext,写锁写入数据
writeLock.lock();
index++;
value.lazySet(o);
writeLock.unlock();
}
static final class BehaviorDisposable<T> implements Disposable, NonThrowingPredicate<Object> {
final Observer<? super T> downstream;
final BehaviorSubject<T> state;
boolean next;
boolean emitting;//用于标识是否在检测缓存数据数据等待发送
AppendOnlyLinkedArrayList<Object> queue;
boolean fastPath;
volatile boolean cancelled;
long index;//用于记录当前下发的次数
BehaviorDisposable(Observer<? super T> actual, BehaviorSubject<T> state) {
this.downstream = actual;
this.state = state;
}
@Override
public void dispose() {
if (!cancelled) {
cancelled = true;
state.remove(this);
}
}
@Override
public boolean isDisposed() {
return cancelled;
}
void emitFirst() {
if (cancelled) {
return;
}
Object o;
synchronized (this) {
if (cancelled) {
return;
}
if (next) {
return;
}
BehaviorSubject<T> s = state;
Lock lock = s.readLock;
lock.lock();
index = s.index;//第一次下发,同步subject的index
o = s.value.get();
lock.unlock();
emitting = o != null;//标记已经在等待下发第一条数据
next = true;
}
if (o != null) {
if (test(o)) {//complete/error事件才返回true
return;
}
//循环尝试下发缓存区中的数据
emitLoop();
}
}
//stateIndex为subject中当次onNext下发的次数
void emitNext(Object value, long stateIndex) {
if (cancelled) {
return;
}
if (!fastPath) {//因为可能第一条数据未下发成功
synchronized (this) {//加锁保证,缓存区检测临界区安全
if (cancelled) {
return;
}
//是当前订阅者的第一条数据的index,即应该emitFirst处理,这里不处理
if (index == stateIndex) {
return;
}
//在检测缓存区数据则将数据加入缓存区
if (emitting) {
AppendOnlyLinkedArrayList<Object> q = queue;
if (q == null) {
q = new AppendOnlyLinkedArrayList<Object>(4);
queue = q;
}
q.add(value);
return;
}
next = true;
}
fastPath = true;
}
test(value);//下发数据
}
@Override
public boolean test(Object o) {//下发数据,#accept仅complete/error事件才返回true
return cancelled || NotificationLite.accept(o, downstream);
}
void emitLoop() {//循环尝试获取缓存区数据下发
for (;;) {
if (cancelled) {
return;
}
AppendOnlyLinkedArrayList<Object> q;
synchronized (this) {//加锁保证,缓存区检测临界区安全
q = queue;
if (q == null) {//无缓存区,标记退出缓存区检测
emitting = false;
return;
}
queue = null;
}
q.forEachWhile(this);//循环尝试调用test方法下发
}
}
}
}
BehaviorSubject是只缓存最近一条数据,当新的订阅者订阅时,将上次最新的数据下发。最近的数据通过AtomicReference<Object> value保存。
- 当第一次订阅时,会调用
BehaviorDisposable#emitFirst下发第一条数据并读取缓存区数据下发 onNext就要考虑如果emitFirst可能在去读缓存区数据则将数据添加如缓存区,否则直接下发
AsyncSubject
AsyncSubject只释放最后一个数据的处理就比较简单,源码里面其实就是在onNext时将数据缓存,在onComplete时先下发再调用下游onComplete,onError则直接下发onError数据不会下发。这里就不贴代码分析了。
SerializedSubject
SerializedSubject其实就是Subject的装饰增强类,通过传入Subject对所有的下发指令(onSubscribe、onNext、onError、onComplete)在下发之前通过synchronized关键字进行状态判断再下发,从而达到线程安全的效果。
内部实现也是类似于BehaviorSubject将所有事件抽象,然后通过读取缓存区进行下发。
UnicastSubject
UnicastSubject仅支持订阅一次。如果多个订阅者试图订阅,若UnicastSubject未terminate,将会收到IllegalStateException ,若已经terminate,那么只会执行onError或者onComplete方法。