关于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
方法。