kotlin 使用flowOn在后台执行操作并在主线程中收集

1l5u6lss  于 11个月前  发布在  Kotlin
关注(0)|答案(1)|浏览(136)

我有下面的代码。我想.flowOn(Dispatchers.IO)将在BackgroundThread中执行map。但是collect将使用Main线程,因为这是coroutineScope启动的线程。

suspend fun main() {
    println("Start")

    println(Thread.currentThread().name)

    coroutineScope {
        launch {
            flowOf(1, 2, 3)
                .map {
                    println(Thread.currentThread().name)
                    it * 2
                }
                .flowOn(Dispatchers.IO)
                .collect {
                        println(Thread.currentThread().name)
                        println("Number: $it")
                }
        }
    }
    println("End")
}

字符串
然而,它打印了以下内容,所以Map和收集都在backgroundThread中:

Start
main
DefaultDispatcher-worker-2
DefaultDispatcher-worker-2
DefaultDispatcher-worker-2
DefaultDispatcher-worker-1
Number: 2
DefaultDispatcher-worker-1
Number: 4
DefaultDispatcher-worker-1
Number: 6
End

unhi4e5o

unhi4e5o1#

你不能用线程名区分IO和默认线程池,因为这两者是耦合在一起的,线程会根据需要在它们之间移动。实现不会在每次更改所有权时更改线程名。
下面的代码可以证明这一点:

import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.withContext

suspend fun main() {
    println(Thread.currentThread().name)
    withContext(Dispatchers.IO) {
        println(Thread.currentThread().name)
    }
    withContext(Dispatchers.Default) {
        println(Thread.currentThread().name)
    }
}

字符串
输出示例:

main
DefaultDispatcher-worker-1
DefaultDispatcher-worker-1


在您的代码中,有证据表明map阶段使用的线程与携带启动的协程的线程不同,因此DefaultDispatcher-worker-2很可能在该运行中被分配给IO分派器。

相关问题