RxJava 比较方便的一点在于线程间的切换,我们可以从上往下下,并且随时实现线程的切换,看个简单的代码
private static void initRxJava1(){
Observable
.create(new Observable.OnSubscribe<String>() {
@Override
public void call(Subscriber<? super String> subscriber) {
System.out.println(" create " + Thread.currentThread().getName() );
subscriber.onNext("hi");
subscriber.onCompleted();
}
})
.subscribeOn(Schedulers.io())
.observeOn(Schedulers.io())
.subscribe(new Subscriber<String>() {
@Override
public void onCompleted() {
System.out.println( "onCompleted " );
}
@Override
public void onError(Throwable e) {
}
@Override
public void onNext(String s) {
System.out.println(s + " " + Thread.currentThread().getName());
}
});
}
打印的结果为
create RxIoScheduler-3
hi RxIoScheduler-2
onCompleted
如果我们把 observeOn(Schedulers.io()) 方法中的 Schedulers.io() 替换为 Schedulers.immediate(),再次打印,结果为
create RxIoScheduler-2
hi RxIoScheduler-2
onCompleted
从上面的例子中,可以看出,io() 和 immediate() 的含义不一样:io() 是新开一个线程, immediate() 是使用当前线程,我们看看调用的源码
Schedulers:
public static Scheduler io() {
return RxJavaHooks.onIOScheduler(getInstance().ioScheduler);
}
private Schedulers() {
...
Scheduler io = hook.getIOScheduler();
if (io != null) {
ioScheduler = io;
} else {
ioScheduler = RxJavaSchedulersHook.createIoScheduler();
}
...
}
RxJavaSchedulersHook:
public static Scheduler createIoScheduler() {
return createIoScheduler(new RxThreadFactory("RxIoScheduler-"));
}
public static Scheduler createIoScheduler(ThreadFactory threadFactory) {
if (threadFactory == null) {
throw new NullPointerException("threadFactory == null");
}
return new CachedThreadScheduler(threadFactory);
}
到此,我们能找到 CachedThreadScheduler 类和 RxThreadFactory 类,先看看 RxThreadFactory,看名字就是个工厂的功能
public final class RxThreadFactory extends AtomicLong implements ThreadFactory {
private static final long serialVersionUID = -8841098858898482335L;
public static final ThreadFactory NONE = new ThreadFactory() {
@Override public Thread newThread(Runnable r) {
throw new AssertionError("No threads allowed.");
}
};
final String prefix;
public RxThreadFactory(String prefix) {
this.prefix = prefix;
}
@Override
public Thread newThread(Runnable r) {
Thread t = new Thread(r, prefix + incrementAndGet());
t.setDaemon(true);
return t;
}
}
这里面核心的方法就是 newThread(),创建线程用的,构造方法中传入 Runnable 和方法名,incrementAndGet() 是 ++ 的意思,原子级别的。再看看 subscribeOn() 方法的源码
Observable:
public final Observable<T> subscribeOn(Scheduler scheduler) {
if (this instanceof ScalarSynchronousObservable) {
return ((ScalarSynchronousObservable<T>)this).scalarScheduleOn(scheduler);
}
return create(new OperatorSubscribeOn<T>(this, scheduler));
}
此时的 this 是 Observable 类型,因此执行if外面的方法,看看 OperatorSubscribeOn 代码
public final class OperatorSubscribeOn<T> implements OnSubscribe<T> {
final Scheduler scheduler;
final Observable<T> source;
public OperatorSubscribeOn(Observable<T> source, Scheduler scheduler) {
this.scheduler = scheduler;
this.source = source;
}
@Override
public void call(final Subscriber<? super T> subscriber) {
final Worker inner = scheduler.createWorker();
subscriber.add(inner);
inner.schedule(new Action0() {
@Override
public void call() {
...
}
});
}
}
省略的部分是回调外面传进来的接口,可以忽略,重点看一下 scheduler.createWorker() 和 inner.schedule() 这两个部分,创建了 Worker 和执行了回调,这里的 scheduler 就是上面提到的 CachedThreadScheduler 类型的对象,看看 createWorker() 方法
public Worker createWorker() {
return new EventLoopWorker(pool.get());
}
pool 是什么,看看代码,它是 AtomicReference<CachedWorkerPool> 类型的对象,在 CachedThreadScheduler 的构造方法中创建,在 start() 中赋值
public CachedThreadScheduler(ThreadFactory threadFactory) {
this.threadFactory = threadFactory;
this.pool = new AtomicReference<CachedWorkerPool>(NONE);
start();
}
@Override
public void start() {
CachedWorkerPool update =
new CachedWorkerPool(threadFactory, KEEP_ALIVE_TIME, KEEP_ALIVE_UNIT);
if (!pool.compareAndSet(NONE, update)) {
update.shutdown();
}
}
也就是说,构造方法中创建了pool对象,并且创建了 CachedWorkerPool 对象,然后把 CachedWorkerPool 装到了pool对象中; pool.get() 对应的就是 CachedWorkerPool。看看 EventLoopWorker 中的 schedule() 方法
@Override
public Subscription schedule(Action0 action) {
return schedule(action, 0, null);
}
@Override
public Subscription schedule(final Action0 action, long delayTime, TimeUnit unit) {
...
ScheduledAction s = threadWorker.scheduleActual(new Action0() {
@Override
public void call() {
if (isUnsubscribed()) {
return;
}
action.call();
}
}, delayTime, unit);
innerSubscription.add(s);
s.addParent(innerSubscription);
return s;
}
注意,这里面有个重点:threadWorker.scheduleActual() 方法。先看看 threadWorker 是什么,它是在 EventLoopWorker 的构造方法中,调用了 CachedWorkerPool 的 get() 方法获取的对象,
CachedWorkerPool:
ThreadWorker get() {
if (allWorkers.isUnsubscribed()) {
return SHUTDOWN_THREADWORKER;
}
while (!expiringWorkerQueue.isEmpty()) {
ThreadWorker threadWorker = expiringWorkerQueue.poll();
if (threadWorker != null) {
return threadWorker;
}
}
ThreadWorker w = new ThreadWorker(threadFactory);
allWorkers.add(w);
return w;
}
从这段代码中可以看到,它有个集合复用的功能,如果集合中有,就使用;如果没有,就创建一个 ThreadWorker 对象,看看它的源码
static final class ThreadWorker extends NewThreadWorker {
private long expirationTime;
ThreadWorker(ThreadFactory threadFactory) {
super(threadFactory);
this.expirationTime = 0L;
}
public long getExpirationTime() {
return expirationTime;
}
public void setExpirationTime(long expirationTime) {
this.expirationTime = expirationTime;
}
}
ThreadWorker 继承 NewThreadWorker,看看它的 scheduleActual() 方法
public ScheduledAction scheduleActual(final Action0 action, long delayTime, TimeUnit unit) {
Action0 decoratedAction = RxJavaHooks.onScheduledAction(action);
ScheduledAction run = new ScheduledAction(decoratedAction);
Future<?> f;
if (delayTime <= 0) {
f = executor.submit(run);
} else {
f = executor.schedule(run, delayTime, unit);
}
run.add(f);
return run;
}
第一行可以忽略,直接看第二行
public final class ScheduledAction extends AtomicReference<Thread> implements Runnable, Subscription {
final Action0 action;
public ScheduledAction(Action0 action) {
this.action = action;
this.cancel = new SubscriptionList();
}
@Override
public void run() {
try {
lazySet(Thread.currentThread());
action.call();
} catch (OnErrorNotImplementedException e) {
signalError(new IllegalStateException("Exception thrown on Scheduler.Worker thread. Add `onError` handling.", e));
} catch (Throwable e) {
signalError(new IllegalStateException("Fatal Exception thrown on Scheduler.Worker thread.", e));
} finally {
unsubscribe();
}
}
...
}
从代码上看,它实现了 Runnable 接口,run() 方法中执行的就是 action.call() 回调。重新回到 scheduleActual() 方法中,接下来就用 executor.submit(run) 或 executor.schedule(run, delayTime, unit) 方法。看看 NewThreadWorker 的构造方法
public NewThreadWorker(ThreadFactory threadFactory) {
ScheduledExecutorService exec = Executors.newScheduledThreadPool(1, threadFactory);
boolean cancelSupported = tryEnableCancelPolicy(exec);
if (!cancelSupported && exec instanceof ScheduledThreadPoolExecutor) {
registerExecutor((ScheduledThreadPoolExecutor)exec);
}
executor = exec;
}
executor 是通过 Executors 的静态方法创建的对象,是 ScheduledThreadPoolExecutor 类型,是个线程池,因此 submit() 和 schedule() 都是开启线程执行 Runnable ,也就是说,子线程是在这里开启的。 ScheduledAction 中的 run() 方法结尾处,有个 unsubscribe() 方法,它是做一些回收的操作,schedule() 方法中调用了 ScheduledAction 的 addParent() 方法添加对象到 cancel 中,而 unsubscribe() 则释放。
void release(ThreadWorker threadWorker) {
// Refresh expire time before putting worker back in pool
threadWorker.setExpirationTime(now() + keepAliveTime);
expiringWorkerQueue.offer(threadWorker);
}
这一步是回收 ThreadWorker 对象,放到集合中,供下一次使用。