kotlin 为什么在Dispatcher.Main和Dispatcher.Default上运行协程会返回相同的结果?

egdjgwm8  于 2023-06-30  发布在  Kotlin
关注(0)|答案(1)|浏览(176)

代码:

import kotlinx.coroutines.*
import kotlin.system.*

fun main() = runBlocking {
    val time = measureTimeMillis {
        println("Outside of child coroutine: ${Thread.currentThread().name}")
        runBlocking() {
            delay(1000)
            println("Inside of child coroutine: ${Thread.currentThread().name}")
        } 
        println("After child coroutine...")
    }
    println("Time: ${time}.ms")
}

运行子runBlocking而不使用任何调度程序时的输出:

Outside of child coroutine: main @coroutine#1
Inside of child coroutine: main @coroutine#2
After child coroutine...
Time: 1010.ms

使用Dispatchers运行子runBlocking时的输出。默认值:

Outside of child coroutine: main @coroutine#1
Inside of child coroutine: DefaultDispatcher-worker-1 @coroutine#2
After child coroutine...
Time: 1027.ms

我知道runBlocking会阻塞调用线程,或者如果我们将runBlocking替换为launch代码将不会阻塞。我的问题是为什么我们要使用调度程序?

hzbexzde

hzbexzde1#

首先,这不是调度员。主。它是main * 函数 * 的线程,用于runBlocking的单线程内部Dispatcher。您的应用中没有UI线程,因此没有Dispatchers.Main。
在你的代码中没有任何东西是与launchasync并行执行的,所以你是按顺序执行的,不管使用的是哪个Dispatcher和线程。
如果你将内部的runBlocking改为launch,那么它将并行运行,但是如果你不使用Dispatchers,默认情况下,它仍然使用main函数中的同一个线程。但是,子协程将在delay()调用期间挂起,这允许该单个线程在再次重用子协程以恢复子协程之前运行协程的其他部分。
基本上,由于您没有任何阻塞代码,因此您不会注意到使用一个线程与多个线程完成工作所需的时间有任何显著差异。
如果您正在执行一些缓慢的阻塞工作,您会注意到使用多线程Dispatcher与仅使用runBlocking线程. Try the following with and without the Dispatchers.Default `之间的区别。

fun main() = runBlocking {
    val time = measureTimeMillis {
        println("Outside of child coroutine: ${Thread.currentThread().name}")
        val job = launch(Dispatchers.Default) {
            Thread.sleep(1000L) // simulate blocking work
            println("Inside of child coroutine: ${Thread.currentThread().name}")
        }  
        Thread.sleep(500L)
        println("After child coroutine...")
        job.join()
        println("Waited for child coroutine...")
    }
    println("Time: ${time}.ms")
}

相关问题