RxJava2 源码分析(三)

目的

本篇主要分析 RxJava2 中的线程池与线程调度时的源码流程。

顺便介绍RxJava2中常用的几个线程池。

上一篇文章,我们的demo中,指定线程时,使用的是 Schedulers 这个类。那我们直接从这个类入手。

Schedulers.java

/**
 * Static factory methods for returning standard Scheduler instances.
 * <p>
 */
public final class Schedulers {...}

一般看一个类的时候,先看注释会让你对这个类又一个全局的概念,它起一个什么作用。

上面的注释说的比较清楚了,它是一个工厂方法,返回一些 Scheduler 对象的实例。

那么下面我们看看 Scheduler 类。

Scheduler.java

这个类提供了API,用来调度工作单元。你可以指定延迟时间,周期性。

我们可以想到很多别的东西,Timer,Executors.newScheduledThreadPool(2)等等

public abstract class Scheduler {...}

这个类的代码不多,我们打开 Structure 视图,可以看到该类的一个结构,这里展示一下 Scheduler 最核心的定义部分:

Scheduler.java

public abstract class Scheduler {

    @NonNull
    public abstract Worker createWorker();

    public Disposable scheduleDirect(@NonNull Runnable run) {
        ...
    }

    public Disposable scheduleDirect(@NonNull Runnable run, long delay, @NonNull TimeUnit unit) {
        ...
    }
    
    @NonNull
    public Disposable schedulePeriodicallyDirect(@NonNull Runnable run, long initialDelay, long period, @NonNull TimeUnit unit) {
        ...
    }

    public abstract static class Worker implements Disposable {
      
        @NonNull
        public Disposable schedule(@NonNull Runnable run) {
            ...
        }

        @NonNull
        public abstract Disposable schedule(@NonNull Runnable run, long delay, @NonNull TimeUnit unit);

        @NonNull
        public Disposable schedulePeriodically(@NonNull Runnable run, final long initialDelay, final long period, @NonNull final TimeUnit unit) {
            ...
        }
    }
}

从上面的定义可以看出,Scheduler 本质上就是用来调度 Runnable 的,支持立即、延时和周期形式的调用

我们从其中一个方法入手,就选择最简单的 public Disposable scheduleDirect(@NonNull Runnable run) {...} 方法。分析完这个方法之后,在看其他的方法,应该就是差不多的了。

Scheduler.java

    public Disposable scheduleDirect(@NonNull Runnable run) {
        return scheduleDirect(run, 0L, TimeUnit.NANOSECONDS);
    }

上面说过,Scheduler 支持延迟调用,那么这里传递0,就表示不延迟。

Scheduler.java

    public Disposable scheduleDirect(@NonNull Runnable run, long delay, @NonNull TimeUnit unit) {
        // ① 创建了一个 Worker
        final Worker w = createWorker();

        // 装饰一下,但是通常会将 run 原封不动的返回
        final Runnable decoratedRun = RxJavaPlugins.onSchedule(run);

        // ② 创建 Task
        DisposeTask task = new DisposeTask(decoratedRun, w);

        // ③ 执行 task
        w.schedule(task, delay, unit);

        return task;
    }

上面的代码中,我加了一点注释,下面来一行一行的分析。

io.reactivex.Scheduler#scheduleDirect(java.lang.Runnable, long, java.util.concurrent.TimeUnit)

final Worker w = createWorker();

由于,Scheduler 是一个抽象类,所以只有它的子类才知道具体的实现,这里我们用 Schedulers.io 为例。

由于篇幅问题,如果这里深入的话,会很容易丢失目标,所以我将 IoScheduler 这个类的分析提出来了,放到了RxJava2 源码分析(2.5)中。

看完这篇文章之后,就知道 Worker 有点像命令,它里面指定了任务需要执行的线程池(因为Worker是Scheduler的子类创建的,Scheduler的子类创建了自己的线程池),当我们调用 work.schedule 的时候,就会将任务交给work中指定的线程池去执行。

这样一来,①处与③处的代码都说清楚了。现在还剩②处的代码。看看 DisposeTask 这个类吧。

DisposeTask

DisposeTask

看它的构造方法与类结构,可以大概猜到它可能会起一个代理委托的作用。

    static final class DisposeTask implements Runnable, Disposable {
        final Runnable decoratedRun;
        final Worker w;

        Thread runner;

        DisposeTask(Runnable decoratedRun, Worker w) {
            this.decoratedRun = decoratedRun;
            this.w = w;
        }

        @Override
        public void run() {
            runner = Thread.currentThread();
            try {
                // 运行 task 中的代码
                decoratedRun.run();
            } finally {
                // 执行完之后,调用 dispose 
                dispose();
                runner = null;
            }
        }

        @Override
        public void dispose() {
            if (runner == Thread.currentThread() && w instanceof NewThreadWorker) {
                // 如果 worker 是 NewThreadWorker,则关闭自己 
                ((NewThreadWorker)w).shutdown();
            } else {
                // 调用 worker 的 dispose
                // 之前我们分析过 IoScheduler.EventLoopWorker 类
                // 它的 dispose 会将自己重新放到线程池中,重复利用
                w.dispose();
            }
        }

        @Override
        public boolean isDisposed() {
            return w.isDisposed();
        }
    }

所以这个类的主要作用是起到一个让 worker 重复利用的作用,但是这只是针对 IoScheduler 的 Worker 来说,别的 Worker 可能会不一样。

因为它调用了 Worker 的 dispose 方法,所以 Worker 的收尾工作可以全部放到这个方法中。

Scheduler类的重要方法都分析完了,其他的方法,就交给你们了。看完了这几篇文章,你应该具有了能够看懂其他 Scheduler 的能力,GOOD LUCK !!!

参考文档

https://juejin.im/post/5b75207ce51d45565d23e093

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
基于Django+python编写开发的毕业生就业管理系统支持学生教师角色+db数据库(毕业设计新项目).zip 【备注】 1、该资源内项目代码都经过测试运行成功,功能ok的情况下才上传的,请放心下载使用!有问题请及时沟通交流。 2、适用人群:计算机相关专业(如计科、信息安全、数据科学与大数据技术、人工智能、通信、物联网、自动化、电子信息等)在校学生、专业老师或者企业员工下载使用。 3、用途:项目具有较高的学习借鉴价值,不仅适用于小白学习入门进阶。也可作为毕设项目、课程设计、大作业、初期项目立项演示等。 4、如果基础还行,或热爱钻研,亦可在此项目代码基础上进行修改添加,实现其他不同功能。 欢迎下载!欢迎交流学习!不清楚的可以私信问我! 基于Django+python编写开发的毕业生就业管理系统支持学生教师角色+db数据库(毕业设计新项目).zip基于Django+python编写开发的毕业生就业管理系统支持学生教师角色+db数据库(毕业设计新项目).zip基于Django+python编写开发的毕业生就业管理系统支持学生教师角色+db数据库(毕业设计新项目).zip基于Django+python编写开发的毕业生就业管理系统支持学生教师角色+db数据库(毕业设计新项目).zip基于Django+python编写开发的毕业生就业管理系统支持学生教师角色+db数据库(毕业设计新项目).zip基于Django+python编写开发的毕业生就业管理系统支持学生教师角色+db数据库(毕业设计新项目).zip基于Django+python编写开发的毕业生就业管理系统支持学生教师角色+db数据库(毕业设计新项目).zip基于Django+python编写开发的毕业生就业管理系统支持学生教师角色+db数据库(毕业设计新项目).zip基于Django+python编写开发的毕业生就业管理系统支持学生教师角色+db数据库(毕业设计新项目).zip
毕设新项目基于python3.7+django+sqlite开发的学生就业管理系统源码+使用说明(含vue前端源码).zip 【备注】 1、该资源内项目代码都经过测试运行成功,功能ok的情况下才上传的,请放心下载使用!有问题请及时沟通交流。 2、适用人群:计算机相关专业(如计科、信息安全、数据科学与大数据技术、人工智能、通信、物联网、自动化、电子信息等)在校学生、专业老师或者企业员工下载使用。 3、用途:项目具有较高的学习借鉴价值,不仅适用于小白学习入门进阶。也可作为毕设项目、课程设计、大作业、初期项目立项演示等。 4、如果基础还行,或热爱钻研,亦可在此项目代码基础上进行修改添加,实现其他不同功能。 欢迎下载!欢迎交流学习!不清楚的可以私信问我! 学生就业管理系统(前端) ## 项目开发环境 - IDE: vscode - node版本: v12.14.1 - npm版本: 6.13.4 - vue版本: @vue/cli 4.1.2 - 操作系统: UOS 20 ## 1.进入项目目录安装依赖 ``` npm install ``` ## 2.命令行执行进入UI界面进行项目管理 ``` vue ui ``` ## 3.编译发布包(请注意编译后存储路径) #### PS:需要将编译后的包复制到后端项目的根目录下并命名为'static' 学生就业管理系统(后端) ## 1.项目开发环境 - IDE: vscode - Django版本: 3.0.3 - Python版本: python3.7.3 - 数据库 : sqlite3(测试专用) - 操作系统 : UOS 20 ## 2.csdn下载本项目并生成/安装依赖 ``` pip freeze > requirements.txt pip install -r requirements.txt ``` ## 3.项目MySQL数据库链接错误 [点击查看解决方法](https://www.cnblogs.com/izbw/p/11279237.html)
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值