Rxjava源码解析--subscribeOn指定线程

基于rxjava1.1.0

用例代码↓
        Observable<String> observable1 = Observable.create(new Observable.OnSubscribe<String>() {
            public void call(Subscriber<? super String> subscriber) {
                Log.e("haha",Thread.currentThread().getName());
                subscriber.onNext("1");
                subscriber.onCompleted();
            }
        });
        
        Subscriber<String> subscriber1 = new Subscriber<String>() {
            @Override
            public void onCompleted() {
            }

            @Override
            public void onError(Throwable e) {
            }

            @Override
            public void onNext(String s) {
                Log.e("haha",s);
                Log.e("haha",Thread.currentThread().getName());
            }
        };

        observable1.subscribeOn(Schedulers.io()).subscribe(subscriber1);
Schedulers 源码精简版
public final class Schedulers {

    private final Scheduler ioScheduler;

    private static final Schedulers INSTANCE = new Schedulers();

    private Schedulers() {
        Scheduler io = RxJavaPlugins.getInstance().getSchedulersHook().getIOScheduler();
        if (io != null) {
            ioScheduler = io;
        } else {
            ioScheduler = new CachedThreadScheduler();
        }
    }

    ①
    public static Scheduler io() {
        return INSTANCE.ioScheduler;
    }
}
subscribeOn精简版↓
public final Observable<T> subscribeOn(Scheduler scheduler) {
        return nest().lift(new OperatorSubscribeOn<T>(scheduler));
    }
OperatorSubscribeOn精简版↓
public class OperatorSubscribeOn<T> implements Operator<T, Observable<T>> {
    private final Scheduler scheduler;

    ②
    public OperatorSubscribeOn(Scheduler scheduler) {
        this.scheduler = scheduler;
    }

   
    @Override
    public Subscriber<? super Observable<T>> call(final Subscriber<? super T> subscriber) {
         ⑥
        final Worker inner = scheduler.createWorker();
        //create subscriber3
        return new Subscriber<Observable<T>>(subscriber) {//subscriber = subscriber 1
            ⑧
            @Override
            public void onNext(final Observable<T> o) {//o = observable1
                //在指定的线程中执行代码
                ⑨
                inner.schedule(new Action0() {

                    @Override
                    public void call() {
                        final Thread t = Thread.currentThread();
                        ⑬
                        o.unsafeSubscribe(new Subscriber<T>(subscriber) {//等价于observable1.onSubscribe1.call(subscriber1)

                            @Override
                            public void onCompleted() {
                                subscriber.onCompleted();
                            }

                            @Override
                            public void onError(Throwable e) {
                                subscriber.onError(e);
                            }

                            @Override
                            public void onNext(T t) {
                                subscriber.onNext(t);
                            }

                        });
                    }
                });
            }
        };
    }
}
lift精简源码↓
public final <R> Observable<R> lift(final Operator<? extends R, ? super T> operator) {
        ③
        //create Observable3  OnSubscribe3
        return new Observable<R>(new OnSubscribe<R>() {
            ④
            @Override
            public void call(Subscriber<? super R> o) {
                ⑤
                Subscriber<? super T> st = hook.onLift(operator).call(o);
                st.onStart();
                ⑦
                onSubscribe.call(st);//onSubscribe2.call(subscriber3)
            }
        });
    }
CachedThreadScheduler代码片段↓
 ⑩
@Override
        public Subscription schedule(Action0 action, long delayTime, TimeUnit unit) {
            if (innerSubscription.isUnsubscribed()) {
                // don't schedule, we are unsubscribed
                return Subscriptions.unsubscribed();
            }
            ⑪
            ScheduledAction s = threadWorker.scheduleActual(action, delayTime, unit);
            innerSubscription.add(s);
            s.addParent(innerSubscription);
            return s;
        }
NewThreadWorker代码片段↓
public ScheduledAction scheduleActual(final Action0 action, long delayTime, TimeUnit unit) {
        Action0 decoratedAction = schedulersHook.onSchedule(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;
    }

代码调用顺序从①开始往后
代码分解
observable1.subscribeOn(Schedulers.io()).subscribe(subscriber1) =
observable1.nest().lift(operatorSubscribeOn(Schedulers.io())).subscribe(subscriber1) =
observable2<observable1>.lift(operatorSubscribeOn(Schedulers.io())).subscribe(subscriber1)

nest()调用的是just(this) 即just(observable1)并且onSubscribe2.call直接调用onNext(observable1)

执行上述代码时未发生订阅关系已经产生一个observable2 onSubscribe2,继续执行代码到达①处创建了ioScheduler 继续执行到达②创建operatorSubscribeOn并制定线程为ioScheduler 继续执行到达③创建observable3 onSubscribe3此时订阅关系变成observable3 .subscribe(subscriber1) 由文章//www.greatytc.com/p/394debafe192知道会执行observable3.onSubscribe3.call(subscriber1)即④处并传入subscriber1

通过⑤创建subscriber3执行到⑥时创建Worker(创建的具体操作由Scheduler的子类去创建这里由CachedThreadScheduler去创建),继续执行到达⑦调用onSubscribe2.call(subscriber3),因为onSubscribe2由just创建 所以直接调用onSubscribe2.onNext(observable1) = subscriber3.onNext(observable1)到达⑧给onNext(o)赋值为observable1

继续执行在⑨的时候调用了Worker.schedule()这段代码到达了⑩继续执行到达⑪最后到达⑫完成了指定线程运行的操作,继续执行Action方法到达⑬ o.unsafeSubscribe(new Subscriber<T>(subscriber) =
observable1.unsafeSubscribe(new Subscriber<T>(subscriber1) =
observable1.onSubscribe1.call(subscriber1)

至此observable1.onSubscribe1.call(subscriber1)已经在指定线程中运行

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 218,525评论 6 507
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 93,203评论 3 395
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 164,862评论 0 354
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 58,728评论 1 294
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 67,743评论 6 392
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,590评论 1 305
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,330评论 3 418
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 39,244评论 0 276
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,693评论 1 314
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,885评论 3 336
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 40,001评论 1 348
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,723评论 5 346
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 41,343评论 3 330
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,919评论 0 22
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 33,042评论 1 270
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 48,191评论 3 370
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,955评论 2 355

推荐阅读更多精彩内容

  • 我从去年开始使用 RxJava ,到现在一年多了。今年加入了 Flipboard 后,看到 Flipboard 的...
    Jason_andy阅读 5,473评论 7 62
  • 前言我从去年开始使用 RxJava ,到现在一年多了。今年加入了 Flipboard 后,看到 Flipboard...
    占导zqq阅读 9,164评论 6 151
  • 最近项目里面有用到Rxjava框架,感觉很强大的巨作,所以在网上搜了很多相关文章,发现一片文章很不错,今天把这篇文...
    Scus阅读 6,880评论 2 50
  • 怎么如此平静, 感觉像是走错了片场.为什么呢, 因为上下游工作在同一个线程呀骚年们! 这个时候上游每次调用emit...
    Young1657阅读 1,469评论 2 1
  • 在正文开始之前的最后,放上 GitHub 链接和引入依赖的 gradle 代码: Github:https://g...
    CHSmile阅读 1,597评论 0 10