1、線程切換使用實例
Observable.create(object:ObservableOnSubscribe<String>{
override fun subscribe(e: ObservableEmitter<String>) {
e.onNext("A")
}
}) .subscribeOn(Schedulers.io()) //設置訂閱線程
.observeOn(AndroidSchedulers.mainThread()) //設置觀察者線程
.subscribe()
- onSubscribe():執行線程就是創建Observable的當前線程,並不訂閱線程、觀察者線程的影響,因爲從源碼中無論看出BasicFuseableObserver還是繼承類中針對onSubscribe()都沒有進行線程操作
public final void onSubscribe(Disposable s) {
if (beforeDownstream()) {
actual.onSubscribe(this);//調用下游的onSubscribe(),層層傳遞
afterDownstream();
}
}
2、observeOn():設置觀察者線程
public final Observable<T> observeOn(Scheduler scheduler) {
return observeOn(scheduler, false, bufferSize());
}
public final Observable<T> observeOn(Scheduler scheduler, boolean delayError, int bufferSize) {
return RxJavaPlugins.onAssembly(new ObservableObserveOn<T>(this, scheduler, delayError, bufferSize));
}
observeOn()操作符最終創建的是ObservableObserveOn對象,在ObservableObserveOn中保存設置的線程,並在執行時切換線程,在ObservableObserveOn的subscribeActual()中創建工作線程保存在Observer中,所以Observe只會作用於下游觀察者
public ObservableObserveOn(ObservableSource<T> source, Scheduler scheduler, boolean delayError, int bufferSize) {
super(source); // 保存Observable
this.scheduler = scheduler; //保存Schedule
this.delayError = delayError;
this.bufferSize = bufferSize;
}
//訂閱執行的方法
@Override
protected void subscribeActual(Observer<? super T> observer) {
if (scheduler instanceof TrampolineScheduler) { //設置爲TrampolineScheduler直接執行
source.subscribe(observer);
} else {
Scheduler.Worker w = scheduler.createWorker(); //
source.subscribe(new ObserveOnObserver<T>(observer, w, delayError, bufferSize));
}
}
2.1、 Scheduler.Worker
這裏設置的是AndroidSchedulers.mainThread(),在AndroidSchedulers中創建HandlerScheduler對象,這裏使用的是Looper.getMainLooper()工作隊列,所以觀察者執行會在主線程中執行
public final class AndroidSchedulers {
private static final class MainHolder {
//使用主線線程隊列創建HandlerScheduler,後面任務都會發送到MainLooper中
static final Scheduler DEFAULT = new HandlerScheduler(new Handler(Looper.getMainLooper()));
}
}
//createWorker()
@Override
public Worker createWorker() {
return new HandlerWorker(handler); // 創建HandlerWorker
}
由上面訂閱分析知道,任務的執行會傳遞到ObserveOnObserver的onNext()中
- ObserveOnObserver():切換線程並響應發送事件
ObserveOnObserver(Observer<? super T> actual, Scheduler.Worker worker, boolean delayError, int bufferSize) {
this.actual = actual; //下游的Observer
this.worker = worker; //創建的工作線程
this.delayError = delayError;
this.bufferSize = bufferSize;
}
@Override
public void onNext(T t) {
if (sourceMode != QueueDisposable.ASYNC) {
queue.offer(t); //添加任務到隊列
}
schedule();
}
void schedule() {
if (getAndIncrement() == 0) {
worker.schedule(this); //執行隊列任務,此處調用的是HandlerWorker
}
}
在ObserveOnObserver的onNext()中首先將發送的事件加入隊列queue中,然後調用schedule()方法,調用worker.schedule()執行隊列任務,這理創建的是HandlerWorker對象,在HandlerWorker的schedule()中發送消息到MainLooper,最終方法執行ObserveOnObserver.run()
private static final class HandlerWorker extends Worker {
private final Handler handler;
HandlerWorker(Handler handler) {
this.handler = handler; // 保存Handler
}
@Override
public Disposable schedule(Runnable run, long delay, TimeUnit unit) {
run = RxJavaPlugins.onSchedule(run);
ScheduledRunnable scheduled = new ScheduledRunnable(handler, run);
Message message = Message.obtain(handler, scheduled);
message.obj = this;
handler.sendMessageDelayed(message, Math.max(0L, unit.toMillis(delay)));
return scheduled;
}
}
- ObserveOnObserver.run():切換線程後執行的任務
@Override
public void run() {
if (outputFused) {
drainFused();
} else {
drainNormal(); //執行主線程中的消息任務
}
}
void drainNormal() {
int missed = 1;
final SimpleQueue<T> q = queue; //獲取隊列
final Observer<? super T> a = actual; //獲取觀察者Observer
for (;;) {
for (;;) {
boolean d = done;
T v;
try {
v = q.poll(); //從隊列中取出數據
} catch (Throwable ex) {
return;
}
a.onNext(v); //向下遊Observer傳遞響應,此時已經找切換的線程中執行了
}
}
}
3、subscribeOn():設置訂閱線程
public final Observable<T> subscribeOn(Scheduler scheduler) {
return RxJavaPlugins.onAssembly(new ObservableSubscribeOn<T>(this, scheduler)); //創建ObservableSubscribeOn實例
}
public ObservableSubscribeOn(ObservableSource<T> source, Scheduler scheduler) {
super(source);
this.scheduler = scheduler;
}
@Override
public void subscribeActual(final Observer<? super T> s) {
final SubscribeOnObserver<T> parent = new SubscribeOnObserver<T>(s); //封裝下游Observer
s.onSubscribe(parent); //執行onSubscribe()
parent.setDisposable(scheduler.scheduleDirect(new SubscribeTask(parent))); //
}
訂閱線程操作符對應的 ObservableSubscribeOn類,ObservableSubscribeOn封裝下游觀察者,在ObservableSubscribeOn的subscribeActual中創建SubscribeTask對象,然後調用scheduler.scheduleDirect()執行SubscribeTask
- SubscribeTask:保存觀察者,並觸發上層Observable的subscribe()執行事件發送
final class SubscribeTask implements Runnable {
SubscribeTask(SubscribeOnObserver<T> parent) {
this.parent = parent; // 保存Observer
}
@Override
public void run() {
source.subscribe(parent); //在切換的線程中執行run()時觸發上層發送事件
}
}
- scheduler.scheduleDirect(…):切換線程
public Disposable scheduleDirect(@NonNull Runnable run, long delay, @NonNull TimeUnit unit) {
final Worker w = createWorker(); //(1)
final Runnable decoratedRun = RxJavaPlugins.onSchedule(run);
DisposeTask task = new DisposeTask(decoratedRun, w); //
w.schedule(task, delay, unit); //(2)執行任務
return task;
}
@Override
public Worker createWorker() {
return new EventLoopWorker(pool.get()); //
}
scheduleDirect()中執行一下邏輯:
- 調用createWorker()創建線程Workrt,傳入緩存Worker池
- 創建DisposeTask保存Worker和Runnable
- 調用Worker執行DisposeTask
- EventLoopWorker:執行任務
EventLoopWorker(CachedWorkerPool pool) {
this.pool = pool;
this.tasks = new CompositeDisposable();
this.threadWorker = pool.get(); //獲取Worker實例,此處獲取的是NewThreadWorker實例
}
public Disposable schedule(@NonNull Runnable action, long delayTime, @NonNull TimeUnit unit) {
return threadWorker.scheduleActual(action, delayTime, unit, tasks); //(3)執行NewThreadWorker中方法
}
- NewThreadWorker():真正使用線程池執行任務的地方
private final ScheduledExecutorService executor = SchedulerPoolFactory.create(threadFactory);//線程池
public Disposable scheduleDirect(final Runnable run, long delayTime, TimeUnit unit) {
ScheduledDirectTask task = new ScheduledDirectTask(RxJavaPlugins.onSchedule(run));
try {
Future<?> f;
if (delayTime <= 0L) {
f = executor.submit(task); //(4)使用線程池執行任務
} else {
f = executor.schedule(task, delayTime, unit);
}
return task;
}
}
- executor.submit(task)任務最後會最終執行SubscribeTask.run()方法,在run()中調用上層被觀察者的subscribe()方法發送事件,此時執行發送事件的線程就切換到設置的訂閱線程
4、Schedule
- ObserverOn()和SubscribeOn()都使用到Schedule去切換工作線程,然後分別在不同的線程中執行操作,二者都是通過創建工作Worker執行事件達到線程切換的目的
public abstract class Scheduler {
public abstract Worker createWorker(); //(1)創建具體工作Worker
//(2)執行工作的方法,最終調用Worker子類中重寫的schedule()
public Disposable scheduleDirect(@NonNull Runnable run, long delay, @NonNull TimeUnit unit) {
final Worker w = createWorker();
w.schedule(task, delay, unit); 調用Worker.schedule()
return task;
}
}
- 總結線程調度:首先傳入Scheduler的繼承類,調用scheduleDirect()執行任務,任務第一步調用重寫方法createWorker()創建具體實現的工作Worker,然後調用Worler.Schedule()執行具體任務,內部創建線程執行達到切換的目的;
- IoScheduler:創建和緩存一組線程池,並使用線程池調度程序
public final class IoScheduler extends Scheduler {
}
- 設置方法,這裏設置RxJava內置線程
Schedulers.io()
- 重寫createWorker()創建具體對應的Worker對象
public Worker createWorker() {
return new EventLoopWorker(pool.get()); //參數:CachedWorkerPool緩存池
}
- EventLoopWorker——IoScheduler中的Worker具體實現類,在schedule()中調用工作線程Threadworker執行任務
EventLoopWorker(CachedWorkerPool pool) {
this.pool = pool; //保存傳入的緩存池
this.tasks = new CompositeDisposable();
this.threadWorker = pool.get(); //從緩存池中獲取工作線程
}
//
public Disposable schedule(@NonNull Runnable action, long delayTime, @NonNull TimeUnit unit) {
return threadWorker.scheduleActual(action, delayTime, unit, tasks);
}
- ThreadWorker——真正執行任務的地方,內部初始化線程池並執行Callable,在Callable中觸發被觀察者事件的發送
//初始化線程池
private final ScheduledExecutorService executor = SchedulerPoolFactory.create(threadFactory);
@NonNull
public ScheduledRunnable scheduleActual(final Runnable run, long delayTime, @NonNull TimeUnit unit, @Nullable DisposableContainer parent) {
Runnable decoratedRun = RxJavaPlugins.onSchedule(run);
ScheduledRunnable sr = new ScheduledRunnable(decoratedRun, parent);
try {
if (delayTime <= 0) { //使用線程池執行任務
f = executor.submit((Callable<Object>)sr);
} else {
f = executor.schedule((Callable<Object>)sr, delayTime, unit);
}
sr.setFuture(f);
}
return sr;
}
- CachedWorkerPool——首先創建Worker實例,內部會使用傳入的線程工廠創建線程池,並將工作線程保存在allWorkers中,當任務完成後調用release()釋放並緩存線程
//獲取工作Worker
ThreadWorker get() {
while (!expiringWorkerQueue.isEmpty()) { //如果緩存池不爲空,取出Worker返回
ThreadWorker threadWorker = expiringWorkerQueue.poll();
if (threadWorker != null) {
return threadWorker;
}
}
ThreadWorker w = new ThreadWorker(threadFactory); //
allWorkers.add(w);
return w;
}
void release(ThreadWorker threadWorker) { //添加緩存的ThreadWorker
threadWorker.setExpirationTime(now() + keepAliveTime); //設置有效期
expiringWorkerQueue.offer(threadWorker); //添加到緩存隊列
}
- 總結線程工作流程:
- 在設置中傳入IOSchedule實例
- 切換線程時調用IOSchedule.scheduleDirect()執行任務
- 調用IOSchedule重寫的createWorker()創建EventLoopWorker實例
- EventLoopWorker中首先從IOSchedule內部緩存池中獲取ThreadWorker實例,如果沒有則創建具體實例並返回
- 調用Worker.schedule()方法執行任務,schedule()方法中調用ThreadWorker.scheduleActual()
- ThreadWorker.scheduleActual()中調用線程池執行任務
- 執行結束後緩存ThreadWorker實例