与 ReactiveCocoa 相比,Rx 的一大优势就是更丰富的并发模型。提到并发,就不得不提多线程。在 RxSwift 中,与线程对应的概念就是调度器,本文就调度器做些介绍,包括并发调度器、串行调度器、RxSwift 内置的调度器,及自定义调度器。

文章地址:https://www.cnblogs.com/xjshi/p/9759551.html

调度器抽象出了执行工作的机制,可以不怎么准确的认为调度器对应原本的线程。

observeOnsubscribeOn 这两个操作符可以与调度器配合使用。

如果你想在一个不同的调度器执行工作,那就使用 observeOn(scheduler) 操作符。

如果没有显式指定 observerOn ,那么工作会在产生元素的调度器来执行。

下边是一个使用 observeOn 的例子:

sequence1
.observeOn(backgroundScheduler)
.map { n in
print("This is performed on the background scheduler")
}
.observeOn(MainScheduler.instance)
.map { n in
print("This is performed on the main scheduler")
}

如果想要序列在指定调度器上生成(subscribe 方法)和 dispose,可以使用 subscribeOn(scheduler)

如果没有明确指定 subscribeOn,那么将在调用 subscribe(onNext:)subscribe 的同一调度器上调用 subscribe 闭包(传递给 Observable.create 的闭包)。

如果没有明确指定 subscribeOn,那么将在启动 disposing 的同一调度器上调用 dispose 方法。

简而言之,如果没有显式的选择调度器,那么将在当前调度器上调用这些方法。

串行调度器 vs 并发调度器

由于调度器可以是任何东西,并且所有转换序列的操作副都需要有额外的保证,因此你创建的是哪种调度器非常重要。

这里的保证是指,对所有的序列(Observable)而言,不论它在那个线程上产生元素,如果序列通过 observer.ron(.next(nextElement)) 将一个元素发送给观察者,那么序列在 observer.on 方法执行结束前不能发送下一个元素。

如果 .next 方法没有执行完成,序列也不能发送终止命令,如 .completed.error

这部分内容在RxSwift 入门一文中介绍过。

如果调度器是并发的,Rx 的 observeOnsubscribeOn 操作符将确保一切正常。

如果你使用Rx可以证明是串行的调度器,它能够执行额外的优化。

在串行调度器的情况下, observeOn 被优化为一个简单的 dispatch_async 调用。

自定义调度器

除了当前的调度器,你也可以实现自己的调度器。

如果你想要描述立即执行工作的调度器,可以实现 ImmediateScheduler 协议。

public protocol ImmediateScheduler {
func schedule<StateType>(state: StateType, action: (/*ImmediateScheduler,*/ StateType) -> RxResult<Disposable>) -> RxResult<Disposable>
}

如果你想要支持基于事件的操作,那么你可以实现 Scheduler 协议:

public protocol Scheduler: ImmediateScheduler {
associatedtype TimeInterval
associatedtype Time var now : Time {
get
} func scheduleRelative<StateType>(state: StateType, dueTime: TimeInterval, action: (StateType) -> RxResult<Disposable>) -> RxResult<Disposable>
}

如果你想有周期执行的能力,你可以通过实现 PeriodicScheduler 协议来通知 Rx。

public protocol PeriodicScheduler : Scheduler {
func schedulePeriodic<StateType>(state: StateType, startAfter: TimeInterval, period: TimeInterval, action: (StateType) -> StateType) -> RxResult<Disposable>
}

内置的调度器

上边我们提到 Rx 可以使用所有类型的调度器,但如果 Rx 可以证明调度器是串行的,那么会执行额外的优化

  1. CurrentThreadScheduler:它是一个串行调度器,表示当前执行工作的调度器。
  2. MainScheduler:抽象了需要在主线程执行的工作,当然也是一个串行调度器。
  3. SerialDispatchQueueScheduler:是一个串行调度器,抽象需要在一个 dispatch_queue_t 上执行的工作,它将确保即时传递并发调度队列(concurrent dispatch queue),它也会转换为串行队列。主调度器 也是 SerialDispatchQueueScheduler 的一个示例。
  4. ConcurrentDispatchQueueScheduler:是一个并发调度器,抽象需要在一个 dispatch_queue_t 上执行的工作。当一些任务需要在后台执行时,使用这个调度器。
  5. OperationQueueScheduler:抽象需要在 NSOperationQueue 上执行的工作。适用于需要在后台执行大量工作,并希望通过使用 maxConcurrentOpeartionCount 来调整并发处理的情况。

本文中的部分表示 与 Rx 中的对照:

本文中的表示 Rx中的表示
调度器 scheduler
串行调度器 serial scheduler
并发调度器 concurrent scheduler

RxSwift 中的调度器的更多相关文章

  1. Spring中Quartz调度器的使用

    一.Quartz的特点 * 按作业类的继承方式来分,主要有以下两种: 1.作业类继承org.springframework.scheduling.quartz.QuartzJobBean类的方式 2. ...

  2. 大数据之Yarn——Capacity调度器概念以及配置

    试想一下,你现在所在的公司有一个hadoop的集群.但是A项目组经常做一些定时的BI报表,B项目组则经常使用一些软件做一些临时需求.那么他们肯定会遇到同时提交任务的场景,这个时候到底如何分配资源满足这 ...

  3. [Spring]支持注解的Spring调度器

    概述 如果想在Spring中使用任务调度功能,除了集成调度框架Quartz这种方式,也可以使用Spring自己的调度任务框架. 使用Spring的调度框架,优点是:支持注解(@Scheduler),可 ...

  4. Erlang/OTP 17.0-rc1 新引入的"脏调度器"浅析

    最近在做一些和 NIF 有关的事情,看到 OTP 团队发布的 17 rc1 引入了一个新的特性“脏调度器”,为的是解决 NIF 运行时间过长耗死调度器的问题.本文首先简单介绍脏调度器机制的用法,然后简 ...

  5. Cocos2d-X3.0 刨根问底(六)----- 调度器Scheduler类源码分析

    上一章,我们分析Node类的源码,在Node类里面耦合了一个 Scheduler 类的对象,这章我们就来剖析Cocos2d-x的调度器 Scheduler 类的源码,从源码中去了解它的实现与应用方法. ...

  6. Hadoop的调度器总结

    Hadoop的调度器总结 随着MapReduce的流行,其开源实现Hadoop也变得越来越受推崇.在Hadoop系统中,有一个组件非常重要,那就是调度器,它的作用是将系统中空闲的资源按一定策略分配给作 ...

  7. Erlang调度器细节探析

    Erlang调度器细节探析 Erlang的很多基础特性使得它成为一个软实时的平台.其中包括垃圾回收机制,详细内容可以参见我的上一篇文章Erlang Garbage Collection Details ...

  8. Linux CFS调度器之task_tick_fair处理周期性调度器--Linux进程的管理与调度(二十九)

    1. CFS如何处理周期性调度器 周期性调度器的工作由scheduler_tick函数完成(定义在kernel/sched/core.c, line 2910), 在scheduler_tick中周期 ...

  9. goroutine与调度器

    29 November 2013 by skoo 我们都知道Go语言是原生支持语言级并发的,这个并发的最小逻辑单元就是goroutine.goroutine就是Go语言提供的一种用户态线程,当然这种用 ...

随机推荐

  1. js学习重点难点知识总结 (巩固闭包、原型、原型链)

    学习重点知识总结   1.闭包知识点巩固        闭包函数:                    1.可以实现函数外部访问函数内部的变量                     2.在Java ...

  2. C++中轻量级多线程openmp

    关于其概念及使用方法: https://baike.baidu.com/item/openmp/3735430?fr=aladdin

  3. 礼盒抖动动画(CocosCreator)

    推荐阅读:  我的CSDN  我的博客园  QQ群:704621321       这个月还有一天了,别问我为什么是一天,996,懂吗?项目是做不完了,策划又加新功能,又不能安静的改bug了.又是动画 ...

  4. 百度地图Canvas实现十万CAD数据秒级加载

    背景 前段时间工作室接到一个与地图相关的项目,我作为项目组成员主要负责地图方面的设计和开发.由于地图部分主要涉及的是前端页面的显示,作为一名Java后端的小白,第一次写了这么多HTML和JavaScr ...

  5. spss分析存在共性线后,接下来是怎么分析?

    在进行线性回归分析时,容易出现自变量(解释变量)之间彼此相关,这种情况被称作多重共线性问题. 适度的多重共线性不成问题,但当出现严重共线性问题时,可能导致分析结果不稳定,出现回归系数的符号与实际情况完 ...

  6. FEL,项目实装记录

    FEL,即Fast EL ,版本0.8,具体内容我就不贴了,自行百度 实装遇到的问题: Spring Boot 打包后无法进行表达式编译. 根据百度以及源码,确定这东西是在用JavaCompiler将 ...

  7. HDU - 3974 Assign the task (DFS建树+区间覆盖+单点查询)

    题意:一共有n名员工, n-1条关系, 每次给一个人分配任务的时候,(如果他有)给他的所有下属也分配这个任务, 下属的下属也算自己的下属, 每次查询的时候都输出这个人最新的任务(如果他有), 没有就输 ...

  8. CountHunter 6101 最优贸易 强联通缩点

    题目传送门 题解:强连通锁点之后. 就成了一副单向图. 然后对于每个点 找到 后面合法的点的最大值就好了. 合法就是后面的那个点可以走到n号点. 也可以正向跑一遍dij 求出到这个点的最小花费. 然后 ...

  9. HDU - 3966 树链刨分

    题目传送门 操作就是询问某个点的值, 然后就是对一条路径上的值全部修改. 最基本的树刨题目了. 树刨的思想: 1. 对于每个点找到他的重儿子. void dfs1(int o, int u){ sz[ ...

  10. U盘便携式hexo&博客搭建&极速纯净低bug主题推荐&部署到coding&SEO优化搜索

    指南:U盘便携式hexo&博客搭建&极速纯净低bug主题推荐&部署到coding&SEO优化搜索   U盘便携式hexo随处写博客 简述:在任意一台联网的电脑上续写he ...