
RxJava
我们先来回顾一下RxJava中的线程切换

如上,RxJava使用
subscribeOn
-
当调用链上只有一个
subscribeOn 时,可以出现在任意位置


上面两种写法效果是一样的:都是在io线程订阅后发射数据 -
当调用链上有多个
subscribeOn 时,只有第一个生效:

上面第二个subscribeOn 没有意义
observeOn
-
observeOn 决定调用链上的后续操作的线程

上面绿线部分的代码将会运行在主线程 -
与
subscribeOn 不同,调用链上允许存在多个observeOn 且每个都有效

上面蓝色绿色部分因为observeOn 的存在分别切换到了不同线程执行
just
RxJava的初学者经常会犯的一个错误是,在
just是立即执行的,不会受

如上,
想要在io执行,需要使用

flatMap
结合上面介绍的RxJava的线程切换,看下面这段代码

如果我们希望
虽然
下面代码可以达到并发执行的效果:

当订阅flatMap返回的Observable时,通过
其他类似flatMap,当涉及到多个Observable的订阅时(例如
Flow
接下来看一下 Flow的线程切换 。
Flow是基于Coroutine的,准确的说应该是Context的切换,所以这部分内容需要你对Croutine事先有基本的了解。

flowOn
说

上面代码中,
与

上面代码,根据颜色可以看出来
launchIn

所以上面代码可能会不符合预期,因为第一个
正确的写法是为每个

或者使用

通过名字可以感觉出来
flowOf

希望

flatMapMerge

如上,2个item各自flatMap成2个item,即一共发射了4条数据,日志输出如下:
1 2 3 4 5 6 7 8 | inner: pool-2-thread-2 @coroutine#4 inner: pool-2-thread-3 @coroutine#5 inner: pool-2-thread-3 @coroutine#5 inner: pool-2-thread-2 @coroutine#4 collect: pool-1-thread-2 @coroutine#2 collect: pool-1-thread-2 @coroutine#2 collect: pool-1-thread-2 @coroutine#2 collect: pool-1-thread-2 @coroutine#2 |
通过日志我们发现
如果将

结果如下:
1 2 3 4 5 6 7 8 | inner: pool-2-thread-2 @coroutine#6 inner: pool-2-thread-1 @coroutine#7 inner: pool-2-thread-2 @coroutine#6 inner: pool-2-thread-1 @coroutine#7 collect: pool-1-thread-3 @coroutine#2 collect: pool-1-thread-3 @coroutine#2 collect: pool-1-thread-3 @coroutine#2 collect: pool-1-thread-3 @coroutine#2 |
但是


通过颜色可以知道
总结
技术对比
RxJava的
| 线程池调度 | 线程操作符 | 数据源异步创建 | 并发执行 | |
|---|---|---|---|---|
| RxJava | Schedulers (io(), computation(), mainThread()) | subscribeOn, observeOn | deffer{} | flatMap(inner subscribeOn) |
| Flow | Dispatchers (IO, Default, Main) | flowOn | flow{} | flatMapMerge(inner or outer flowOn) |
从RxJava迁移到Flow
最后通过一个例子看一下如何将代码从RxJava迁移到Flow
RxJava
RxJava代码如下:

使用到的

代码执行结果:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 | 1: pool-1-thread-1 1: pool-1-thread-1 1: pool-1-thread-1 2: pool-3-thread-1 2: pool-3-thread-1 2: pool-3-thread-1 inner 1: pool-4-thread-1 inner 1: pool-4-thread-2 inner 1: pool-4-thread-1 inner 1: pool-4-thread-1 inner 1: pool-4-thread-2 inner 1: pool-4-thread-2 inner 1: pool-4-thread-3 inner 2: pool-5-thread-1 inner 2: pool-5-thread-2 3: pool-5-thread-1 inner 2: pool-5-thread-2 inner 1: pool-4-thread-3 inner 2: pool-5-thread-2 inner 2: pool-5-thread-3 3: pool-5-thread-1 3: pool-5-thread-1 3: pool-5-thread-1 end: pool-6-thread-1 end: pool-6-thread-1 inner 1: pool-4-thread-3 end: pool-6-thread-1 3: pool-5-thread-1 inner 2: pool-5-thread-1 3: pool-5-thread-1 inner 2: pool-5-thread-3 inner 2: pool-5-thread-1 end: pool-6-thread-1 3: pool-5-thread-3 3: pool-5-thread-3 end: pool-6-thread-1 inner 2: pool-5-thread-3 3: pool-5-thread-3 end: pool-6-thread-1 end: pool-6-thread-1 end: pool-6-thread-1 end: pool-6-thread-1 |
代码非常长,我们借助颜色标记法帮我们理清线程关系

上色后一目了然了,需要特别注意的是由于flatMap中切换了数据源的同时切换了线程,所以打印
Flow
首相创建对应的

然后将代码换成Flow的写法,主要遵循下列原则
- RxJava通过
observeOn 切换后续代码的线程 - Flow通过
flowOn 切换前置代码的线程

打印结果如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 | 1: pool-1-thread-1 @coroutine#6 1: pool-1-thread-1 @coroutine#6 1: pool-1-thread-1 @coroutine#6 2: pool-2-thread-2 @coroutine#5 2: pool-2-thread-2 @coroutine#5 2: pool-2-thread-2 @coroutine#5 inner 1: pool-3-thread-1 @coroutine#10 inner 1: pool-3-thread-2 @coroutine#11 inner 1: pool-3-thread-3 @coroutine#12 inner 1: pool-3-thread-2 @coroutine#11 inner 1: pool-3-thread-3 @coroutine#12 inner 2: pool-4-thread-3 @coroutine#9 inner 1: pool-3-thread-1 @coroutine#10 inner 1: pool-3-thread-3 @coroutine#12 inner 1: pool-3-thread-2 @coroutine#11 inner 2: pool-4-thread-1 @coroutine#7 inner 2: pool-4-thread-2 @coroutine#8 inner 2: pool-4-thread-1 @coroutine#7 inner 2: pool-4-thread-3 @coroutine#9 inner 1: pool-3-thread-1 @coroutine#10 3: pool-4-thread-1 @coroutine#3 inner 2: pool-4-thread-3 @coroutine#9 inner 2: pool-4-thread-2 @coroutine#8 end: pool-5-thread-1 @coroutine#2 3: pool-4-thread-1 @coroutine#3 inner 2: pool-4-thread-2 @coroutine#8 3: pool-4-thread-1 @coroutine#3 end: pool-5-thread-1 @coroutine#2 3: pool-4-thread-1 @coroutine#3 end: pool-5-thread-1 @coroutine#2 end: pool-5-thread-1 @coroutine#2 3: pool-4-thread-1 @coroutine#3 3: pool-4-thread-1 @coroutine#3 end: pool-5-thread-1 @coroutine#2 end: pool-5-thread-1 @coroutine#2 3: pool-4-thread-1 @coroutine#3 3: pool-4-thread-1 @coroutine#3 end: pool-5-thread-1 @coroutine#2 end: pool-5-thread-1 @coroutine#2 inner 2: pool-4-thread-1 @coroutine#7 3: pool-4-thread-1 @coroutine#3 end: pool-5-thread-1 @coroutine#2 |
从日志可以看到,





