加深对RxJava线程切换的理解之ObserveOn和SubscribeOn

2023-05-16

这几天看到一篇些文章,关于RxJava线程切换的,说到RxJava的线程切换,就一定会涉及ObserveOn和SubscribeOn两个方法。

网上对于ObserveOn和SubscribeOn的调用顺序、调用有效等有很多文章,读者可以自行搜索。

胖子只是为了加深对RxJava线程切换的理解,同时完善一些网上结论不严谨的地方,毕竟实践出真理。

这里只做结论,对于原理,会另起一篇,介绍RxJava原理机制时,详细介绍。

先来说说大概介绍下ObserveOn和SubscribeOn分别是做什么的,看官网的描述和图

As shown in this illustration, the SubscribeOn operator designates which thread the 
Observable will begin operating on, no matter at what point in the chain of operators 
that operator is called. ObserveOn, on the other hand, affects the thread that the 
Observable will use below where that operator appears. For this reason, you may call 
ObserveOn multiple times at various points during the chain of Observable operators in 
order to change on which threads certain of those operators operate.
翻译
如此图所示,SubscribeOn运算符指定Observable将在哪个线程上开始操作,无论该运算符在运算符链中的哪个点被调用。另一方面,ObserveOn影响Observable将在该运算符出现的位置使用的线程。因此,您可以在Observable运算符链中的各个点多次调用ObserveOn,以更改某些运算符在哪些线程上进行操作。
比较通熟易懂点的结论:
     1.SubscribeOn切换的是订阅的线程
     2.ObserveOn切换的是发送的线程
再通熟易懂点一点:
     1.SubscribeOn切换的是Observable执行的线程
     2.ObserveOn改切换的是观察Observable的线程
简单、粗暴:
     1.SubscribeOn在ObserveOn调用前,切换网络请求、IO等耗时操作的线程。
     2.耗时操作完后,ObserveOn切换回来,更新UI。

ObserveOn和SubscribeOn.png

关于subscribeOn

activityMainBinding.button.setOnClickListener(v->{
            Observable.just(3)//传一个3
                    .subscribeOn(Schedulers.newThread())//注意这里1
                    .map(str->{
                        Log.e(TAG, "第一次map,参数 = "+str+",当前线程 = "+Thread.currentThread().getName());
                        return Math.pow(str,2);
                    })
                    .subscribeOn(Schedulers.newThread())//注意这里2
                    .map(str->{
                        Log.e(TAG, "第二次map,参数 = "+str+",当前线程 = "+Thread.currentThread().getName());
                        return Math.pow(str,2);
                    })
                    .subscribeOn(Schedulers.newThread())//注意这里3
                    .map(str->{
                        Log.e(TAG, "第三次map,参数 = "+str+",当前线程 = "+Thread.currentThread().getName());
                        return Math.pow(str,2);
                    })
                    .subscribe(integer->{
                Log.e(TAG,"最后接收到的为" + integer+",当前线程 = "+Thread.currentThread().getName());
            });
        });

image-20200925140548098.png再来看看另一种

activityMainBinding.button.setOnClickListener(v->{
            Observable.just(3)//传一个3
                    .subscribeOn(Schedulers.newThread())//注意这里1
                    .map(str->{
                        Log.e(TAG, "第一次map,参数 = "+str+",当前线程 = "+Thread.currentThread().getName());
                        return Math.pow(str,2);
                    })
                    .subscribeOn(Schedulers.io())//注意这里2
                    .map(str->{
                        Log.e(TAG, "第二次map,参数 = "+str+",当前线程 = "+Thread.currentThread().getName());
                        return Math.pow(str,2);
                    })
                    .subscribeOn(AndroidSchedulers.mainThread())//注意这里3
                    .map(str->{
                        Log.e(TAG, "第三次map,参数 = "+str+",当前线程 = "+Thread.currentThread().getName());
                        return Math.pow(str,2);
                    })
                    .subscribe(integer->{
                Log.e(TAG,"最后接收到的为" + integer+",当前线程 = "+Thread.currentThread().getName());
            });
        });

image-20200925141306317.png再来

activityMainBinding.button.setOnClickListener(v->{
            Observable.just(3)//传一个3
                    .subscribeOn(Schedulers.newThread())
                    .map(str->{
                        Log.e(TAG, "第一次map,参数 = "+str+",当前线程 = "+Thread.currentThread().getName());
                        return Math.pow(str,2);
                    })
                    .subscribeOn(Schedulers.newThread())
                    .map(str->{
                        Log.e(TAG, "第二次map,参数 = "+str+",当前线程 = "+Thread.currentThread().getName());
                        return Math.pow(str,2);
                    })
                    .subscribeOn(AndroidSchedulers.mainThread())
                    .map(str->{
                        Log.e(TAG, "第三次map,参数 = "+str+",当前线程 = "+Thread.currentThread().getName());
                        return Math.pow(str,2);
                    })
                    .subscribe(integer->{
                Log.e(TAG,"最后接收到的为" + integer+",当前线程 = "+Thread.currentThread().getName());
            });
        });

image-20200925141651668.png再来

activityMainBinding.button.setOnClickListener(v->{
            Observable.just(3)//传一个3
                    .subscribeOn(Schedulers.io())
                    .map(str->{
                        Log.e(TAG, "第一次map,参数 = "+str+",当前线程 = "+Thread.currentThread().getName());
                        return Math.pow(str,2);
                    })
                    .subscribeOn(Schedulers.io())
                    .map(str->{
                        Log.e(TAG, "第二次map,参数 = "+str+",当前线程 = "+Thread.currentThread().getName());
                        return Math.pow(str,2);
                    })
                    .subscribeOn(Schedulers.io())
                    .map(str->{
                        Log.e(TAG, "第三次map,参数 = "+str+",当前线程 = "+Thread.currentThread().getName());
                        return Math.pow(str,2);
                    })
                    .subscribe(integer->{
                Log.e(TAG,"最后接收到的为" + integer+",当前线程 = "+Thread.currentThread().getName());
            });
        });

image-20200925144538226.png

对于subscribeOn

不同的调用,只保留第一次调用。

如:

.subscribeOn(Schedulers.newThread())//保留

.subscribeOn(AndroidSchedulers.mainThread())

Schedulers.io()多次调用,调用次数为双数为2,单数为1。

如:

.subscribeOn(Schedulers.io())会切换到RxCachedThreadScheduler-1

or

.subscribeOn(Schedulers.io())

.subscribeOn(Schedulers.io())会切换到RxCachedThreadScheduler-2

or

.subscribeOn(Schedulers.io())

.subscribeOn(Schedulers.io())

.subscribeOn(Schedulers.io())会切换到RxCachedThreadScheduler-1

…以此内推

Schedulers.newThread()多次调用,叠加。

如:

.subscribeOn(Schedulers.newThread())

.subscribeOn(Schedulers.newThread())

.subscribeOn(Schedulers.newThread())会切换到RxNewThreadScheduler-3

关于ObserveOn

activityMainBinding.button.setOnClickListener(v->{
    Observable.just(3)//传一个3
            .observeOn(Schedulers.newThread())//第一次切换
            .map(str->{
                Log.e(TAG, "第一次map,参数 = "+str+",当前线程 = "+Thread.currentThread().getName());
                return Math.pow(str,2);
            })
            .observeOn(Schedulers.io())//第二次切换
            .map(str->{
                Log.e(TAG, "第二次map,参数 = "+str+",当前线程 = "+Thread.currentThread().getName());
                return Math.pow(str,2);
            })
            .observeOn(AndroidSchedulers.mainThread())//第三次切换
            .map(str->{
                Log.e(TAG, "第三次map,参数 = "+str+",当前线程 = "+Thread.currentThread().getName());
                return Math.pow(str,2);
            })
            .subscribe(integer->{
        Log.e(TAG,"最后接收到的为" + integer+",当前线程 = "+Thread.currentThread().getName());
    });
});

image-20200925143403055.pngobserveOn比较直接,调用一次,切换一次,次次生效。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

加深对RxJava线程切换的理解之ObserveOn和SubscribeOn 的相关文章

  • datetime与timestamp

    mysql数据库表示时间类型的数据分别是date datetime time timestamp和year date xff1a yyyy mm dd 格式表示的日期值 xff1b time xff1a hh mm ss 格式表示的时间值
  • [vue-i18n] Value of key '图标管理' is not a string!

    今天项目运行时报了很多vue i18n esm js a925 14 vue i18n Value of key 图标管理 is not a string 的错 xff1a 解决方案 xff1a 在项目的index js文件中修改配置 xf
  • 996,活着抑或死亡

    就在昨天 xff0c 2021年元旦假期的最后一天 xff0c 网传某大厂多多买菜的23岁小姑娘离开了这个世界 不久之前 xff0c 也有另一大厂的朋友因工作强度太大 xff0c 在字节跳动与心脏跳动中选择了后者 还有更戏剧化的新闻是刚因大
  • 2018年度总结

    2019新的一年到了 xff0c 又是一年到收获的季节 xff0c 在去年自己见证了师哥师姐的收获 xff0c 支付宝的出了自己的消费清单 xff0c 自己给自己一份2018年度成长清单 计算机 今年开始学习java xff0c 从开始的不
  • 模糊查询

    lt select id 61 34 findByUserIdMonthAttend 34 resultMap 61 34 BaseResultMap 34 gt SELECT lt include refid 61 34 Base Col
  • 字符串连接

    StringBuilder StringBuffer String三者区别 1 运行速度 xff0c 在这方面运行速度快慢为 xff1a StringBuilder gt StringBuffer gt String String最慢的原因
  • 集合

    Java集合类存放于 java util 包中 xff0c 是一个用来存放对象的容器 集合只能存放对象 比如你存一个 int 型数据 1放入集合中 xff0c 其实它是自动转换成 Integer 类后存入的 xff0c Java中每一种基本
  • 事务

    事务必须服从ISO IEC所制定的ACID原则 ACID是原子性 xff08 atomicity xff09 一致性 xff08 consistency xff09 隔离性 xff08 isolation xff09 和持久性 xff08
  • vue select 获取value和lable

    vue select控件在选择时需要把id和name两个值都获取到 xff0c 实现方案如下 xff1a select控件代码 lt FormItem label 61 34 物资类型 xff1a 34 prop 61 34 supplyT
  • vue中render函数子组件调用父组件方法

    父组件render函数内容 return h swichbutton swichbutton为子组件 props row params row valveState props声明给子组件传递的参数 xff0c 子组件通过以下方式接收 pr
  • Couldn't find preset "es2015" relative to directory

    修改 babelrc文件内容如下 xff0c 运行后报错 Module build failed Error Couldn t find preset es2015 relative to directory 34 presets 34 3
  • vue运行同时被localhost和ip地址访问

    在index js文件下修改host内容 xff0c localhost改为本机ip host 39 192 168 X XX 39 can be overwritten by process env HOST port 8080 can
  • AppData\Roaming\npm-cache\_logs

    npm install报如下错误 xff1a npm ERR code ELIFECYCLE npm ERR errno 1 npm ERR bhwechat 64 1 0 0 dev 96 webpack dev server inlin
  • 你和高手的差距,就在一念之间

    我一直做软件开发和技术管理工作 xff0c 虽然在做联合创始人期间也参与2B的市场销售运营等众多事情 xff0c 但2C的电商卖货这件事从未体验过 想起小学时学的小马过河的故事 xff0c 要想知道怎么做 xff0c 不能只听别人的说法 x
  • 动态IF语句拼接sql语句

    动态IF语句拼接sql语句 lt 列表 正式 非居民 gt lt select id 61 34 listFormatNodWeller 34 resultType 61 34 com jczb binhe oa model Nodwell
  • swagger基本注解

    与使用Swagger核心注释注释模型类以提供其他元数据相同 xff0c 可以注释控制器及其方法和方法参数 64 Api描述了整个控制器 64 ApiOperation用于方法级别的描述 64 ApiParam用于方法参数 64 RestCo
  • sql语句foreach

    lt 查询 新户水表信息 gt lt select id 61 34 getWaterMeterStartByMeterCodeNew 34 parameterType 61 34 com jczb binhe oa model Water
  • groupconcat函数

    比如select group concat name MySQL中group concat函数 语法如下 xff1a group concat DISTINCT 要连接的字段 Order BY ASC DESC 排序字段 Separator
  • echart百度地图取消点击事件

    在下载的nodemodule包中修改代码 var bmap 61 bmapModel bmap 61 new BMap Map bmapRoot enableMapClick false
  • JavaEE规范

    十三个规范为 xff1a JDBC xff08 java Database Connectivity xff09 xff1a JDBC API为访问不同的数据库提供了一种统一的途径 JNDI Java Name and Directory

随机推荐

  • Java反射

    什么时候用 Java程序中许多对象在运行时出现两种类型 xff1a 编译时类型和运行时类型 xff0c 例如Person p 61 New Student 这时生成的p变量的编译时类型为Person xff0c 运行时类型为Student
  • css3 animation 实现帧动画

    先上代码 xff1a lt DOCTYPE html gt lt html gt lt head gt lt title gt lt title gt lt style gt ani container width 125px height
  • 从原理到实战:vue中的provide/inject让你的代码更优美

    前言 关于 vue 中的 provide inject 这一主题 xff0c 它可以被看作是一种高级的依赖注入机制 xff0c 允许跨层级组件实现状态共享 xff0c 从而提高代码的可维护性和扩展性 在这篇文章中 xff0c 我将从原理到实
  • Struts2框架下使用Kindeditor上传图片

    之前的项目是用Spring的模式上传Kindeditor图片到服务器 xff0c 但是现在这个项目里面只有Struts2框架所以跟Spring不一样 xff0c 以下为代码 xff1a public Object fileUpload St
  • 8大话题,解惑企业数字化

    从IT到DT xff0c 从信息化到数字化 xff0c 这个观念已经毋庸置疑 xff0c 但是 xff0c 这条路却缺少参照 xff0c 暗夜前行 xff0c 全靠摸索 关于数字化 xff0c 肯定不是上马一些OA工具 购买一些营销工具就行
  • python爬取网易云音乐

    只需要吧这个id替换掉代码中的id就可以了 span class token comment http music 163 com song media outer url id 61 为网易云的下载连接更换id即可 span span c
  • linux环境下常用的查找命令find、which、grep

    文章目录 前言find命令格式具体示例 locate命令格式具体示例 whereis命令格式具体示例 which命令格式具体示例 grep命令格式具体示例 总结 前言 查找是运维工作的很重要的一部分 xff0c 不管是文件查找 xff0c
  • 网络编程学习(9)/ FTP项目(3) ——目录切换、目录查看功能

    网络编程学习 xff08 9 xff09 FTP项目 xff08 3 xff09 目录切换 目录查看功能 调用功能函数以及对参数数量进行判断客户端 96 server 文件夹下 FTPClient py 96 状态码的变化服务端 96 li
  • [入门] 用java输出一个HelloWorld并运行

    你好 陌生人 今天是我第一次写博客 内容与知识等方面都不成熟 请见谅 如何在java里运行一个HelloWorld文本 首先 创建一个记事本 取名为HelloWorld 后缀名为java 然后打开记事本输入 public class Hel
  • 标识符与数据类型

    标识符 Java 语言中 xff0c 对各种变量 方法和类等要素命名时使用的字符序列称为标识符 Java 标识符有如下命名规则 xff1a 标识符由字母 下划线 美元符 或数字组成 标识符应以字母 下划线 美元符开头 Java 标识符大小写
  • 线程运行的几个状态

    1 创建状态 New 创建一个新的线程对象 已经有了空间和其他资源 2 就绪状态 Runnable 属于等待状态或可运行状态 若其他线程调用了该对象start 方法 从而启动线程 处于就绪状态的线程 等待cpu的使用权限执行 3 阻塞状态
  • Javaweb转发

    概念 请求转发 xff1a request getRequestDispatcher 要转发的URL地址 forward request response 是一次请求 xff0c 转发后请求对象会保存 xff0c 但是它的地址不会发生变化
  • Javaweb重定向

    概念 首先向客户浏览器发送一个http请求 当服务器接收后发送一个响应状态码302 对应一个新的浏览器地址 新的浏览器地址发现有一个302响应状态码 跳转到对应地址 可以这样理解 浏览器要访问oneServlet 可是oneServlet搬
  • 面试题总结(一)

    1 char型变量中能不能存贮一个中文汉字 为什么 char型变量是用来存储Unicode编码的字符的 xff0c unicode编码字符集中包含了汉字 xff0c 所以 xff0c char型变量中当然可以存储汉字啦 不过 xff0c 如
  • SSM整合

    什么是ssm 通常指的是spring springmvc和mabatis 1 xff09 Spring Spring 是一个开源框架 xff0c Spring 是于 2003 年兴起的一个轻量级的 Java 开发框架 xff0c 由 Rod
  • 在这个艰难的环境下,我裸辞了

    2022年 xff0c 疫情期间 xff0c 工作了22年的我 xff0c 从软件研发管理的相关工作中 xff0c 辞职创业 xff0c 开启我的独立咨询顾问生涯 很多人不解和迷惑 xff0c 也有朋友关切的询问我的近况 xff0c 就差用
  • 反射的简要

    什么是反射 Java反射机制是在运行状态中 xff0c 对于任意一个类 xff0c 都能够知道这个类的所有属性和方法 xff0c 对于任意一个对象 xff0c 都能够调用它的任意一个方法和属性 xff0c 这种动态获取的信息以及动态调用对象
  • Lenovo system X3650 M5安装Windows Server 2008 R2简易教程

    目标 xff1a 在Lenovo System X3650上安装Windows Server 2008 R2 xff08 建议安装windows server 2012 R2 xff09 准备工具 U盘和空白光盘 xff0c DVD刻录机
  • 空间相关分析(一) 空间权重矩阵

    之前的博客分享了各行政区shp文件的制作方法 xff0c 在拿到shp文件后就可以进行空间相关分析啦 今天来介绍一下相关理论的基础 空间权重矩阵的创建 目录 定义介绍Geoda创建空间权重矩阵Arcgis创建空间权重矩阵 定义介绍 根据地理
  • 加深对RxJava线程切换的理解之ObserveOn和SubscribeOn

    这几天看到一篇些文章 xff0c 关于RxJava线程切换的 xff0c 说到RxJava的线程切换 xff0c 就一定会涉及ObserveOn和SubscribeOn两个方法 网上对于ObserveOn和SubscribeOn的调用顺序