RxJava2源码分析(三):线程调度分析1

简介: 线程调度分析

前言:经过前面两篇文章对RxJava2源码的分析,我们已经对RxJava2的基本流程及操作符的原理有了一定程度的认识。这篇文章将在前面两篇文章的基础上,对RxJava2的线程调度进行分析,建议先阅读前面两篇的文章,再阅读本文。

注:文章内容过多,建议在空闲时阅读。

相关文章

示例代码

  为了更好的理解RxJava2的线程调度原理,不被其他的代码所干扰,这里就只贴出与线程调度有关的代码,如下

private void threadScheduleCode() {
        Observable.create(new ObservableOnSubscribe<String>() {
            @Override
            public void subscribe(ObservableEmitter<String> emitter) throws Exception {
                Log.e("wizardev", "上游所在的线程: "+Thread.currentThread().getName());
                Thread.sleep(2*1000);
                emitter.onNext("wizardev");
            }
        }).subscribeOn(Schedulers.io())
                .observeOn(AndroidSchedulers.mainThread())
                .subscribe(new Observer<String>() {
                    @Override
                    public void onSubscribe(Disposable d) {
                        Log.e("wizardev", "onSubscribe: "+Thread.currentThread().getName() );
                    }
                    @Override
                    public void onNext(String s) {
                        Log.e("wizardev", "接收到上游发射的数据为: " + s);
                        Log.e("wizardev", "下游所在的线程: "+ Thread.currentThread().getName());
                    }
                    @Override
                    public void onError(Throwable e) {
                    }
                    @Override
                    public void onComplete() {
                    }
                });
    }

可以看下执行这段代码后打印的日志,如下

e4536bf73c83437b30bb2dac9a5d498.png

可以发现上游和下游确实不在同一个线程中,那么RxJava2是怎么进行线程切换的呢?想知道答案,请继续阅读本文。

本文要解决的问题

  本文要解决的问题其实就一个,就是RxJava2是如何进行线程调度的?但是,围绕着这个问题又会有两个小的问题需要解决:

  1. subscribeOn是怎样将要处理的数据放到到工作线程的?
  2. observeOn是怎样将工作线程切换到主线程的?

为了能够更容易理解线程调度的原理,这里对源码分析的顺序将会按照代码的执行顺序进行分析。

subscribeOn方法分析

  因为前面的文章已经分析过了create方法,所以就直接分析subscribeOn这个方法,直接上源码,如下

public final Observable<T> subscribeOn(Scheduler scheduler) {
        ObjectHelper.requireNonNull(scheduler, "scheduler is null");
        return RxJavaPlugins.onAssembly(new ObservableSubscribeOn<T>(this, scheduler));
    }

有了前面分析源码的经验,可以知道,subscribeOn方法其实就是返回了ObservableSubscribeOn类的实例并将上游的ObservableCreate和subscribeOn方法的参数注入到了它的构造方法中。 继续看下ObservableSubscribeOn类的源码,如下

public final class ObservableSubscribeOn<T> extends AbstractObservableWithUpstream<T, T> {
    final Scheduler scheduler;
    public ObservableSubscribeOn(ObservableSource<T> source, Scheduler scheduler) {
        super(source);
        this.scheduler = scheduler;
    }
    @Override
    public void subscribeActual(final Observer<? super T> observer) {
        final SubscribeOnObserver<T> parent = new SubscribeOnObserver<T>(observer);
        observer.onSubscribe(parent);
        parent.setDisposable(scheduler.scheduleDirect(new SubscribeTask(parent)));
    }
    //...
    //省略部分源码
}

从源码中可以看到,这里分别将ObservableCreate类的实例以及subscribeOn方法的参数即Schedulers.io()作为了ObservableSubscribeOn类的成员变量。 好了,上面的这些就是执行

subscribeOn(Schedulers.io())

这句代码所做的事情了,下面来看下

observeOn(AndroidSchedulers.mainThread())

这句代码所做的事情。


相关文章
|
2月前
|
Linux
一个进程最多可以创建多少个线程基本分析
一个进程最多可以创建多少个线程基本分析
285 1
|
2月前
|
监控 Linux 编译器
多线程死锁检测的分析与实现(linux c)-有向图的应用
在日常的软件开发中,多线程是不可避免的,使用多线程中的一大问题就是线程对锁的不合理使用造成的死锁,死锁一旦发生,将导致多线程程序响应时间长,吞吐量下降甚至宕机崩溃,那么如何检测出一个多线程程序中是否存在死锁呢?在提出解决方案之前,先对死锁产生的原因以及产生的现象做一个分析。最后在用有向环来检测多线程中是否存在死锁的问题。
70 0
|
25天前
|
存储 SQL 监控
JAVA 线程池的分析和使用
JAVA 线程池的分析和使用
19 0
|
2月前
|
SQL Dubbo Java
案例分析|线程池相关故障梳理&总结
本文作者梳理和分享了线程池类的故障,分别从故障视角和技术视角两个角度来分析总结,故障视角可以看到现象和教训,而技术视角可以透过现象看到本质更进一步可以看看如何避免。
84687 136
案例分析|线程池相关故障梳理&总结
|
2月前
|
资源调度 算法 Linux
Linux进程/线程的调度机制介绍:详细解析Linux系统中进程/线程的调度优先级规则
Linux进程/线程的调度机制介绍:详细解析Linux系统中进程/线程的调度优先级规则
546 0
|
8天前
|
消息中间件 Java 数据安全/隐私保护
线程间通信的方法与比较分析
线程间通信的方法与比较分析
|
10天前
|
Java 数据库连接 调度
Java多线程,对锁机制的进一步分析
Java多线程,对锁机制的进一步分析
|
2月前
|
算法 调度
【操作系统】处理机调度的基本概念和三个层次、进程调度的时机和方式、调度器、闲逛线程
【操作系统】处理机调度的基本概念和三个层次、进程调度的时机和方式、调度器、闲逛线程
164 3
|
2月前
|
Java
【Java多线程】分析线程加锁导致的死锁问题以及解决方案
【Java多线程】分析线程加锁导致的死锁问题以及解决方案
46 1
|
2月前
|
存储 Java 调度
Java多线程基础-1:通俗简介操作系统之进程的管理与调度
操作系统是一个复杂的软件,具备许多功能。其中,进程的管理与调度是与我们密切相关的。本文将对操作系统功能中进程管理与调度作出介绍。
32 0