Kotlin 启动与启动(Dispatchers.Default)

标签 kotlin kotlin-coroutines

为了我自己的理解,我正在测试阻塞代码和协程如何交互。显然,我们应该使用非阻塞,但我想了解如果其中有一些阻塞代码会发生什么。

如果我运行以下命令:

fun main() {
    println("Start: ${Thread.currentThread()}")
    runBlocking {
        println("Run Blocking : ${Thread.currentThread()}")
        launch(Dispatchers.D) { // Immediately scheduled for execution
            println("Inside launch: ${Thread.currentThread()}")
        }
        Thread.sleep(10000)
        println("Going to do some other stuff now")
    }
    println("Out of runBlocking")

}

一切都在同一个协程中运行,并且 Inside launch:Thread.sleep 完成之前不会出现。我认为这是因为它是阻塞的,所以不会发生挂起或使用另一个协程。

如果我将 Dispatchers.Default 传递给 launch(我认为 launch 默认使用 Dispatchers.Default,如果你没有指定的话?),启动 block 在单独的协程中运行并立即启动。

那么,为什么 launch(Dispatchers.Default) 允许第二个协程启动,为什么不直接 launch 呢?

最佳答案

I thought launch used Dispatchers.Default by default, if you didn't specify one

这是你弄错的地方。这是 documentation :

The coroutine context is inherited from a CoroutineScope. Additional context elements can be specified with context argument. If the context does not have any dispatcher nor any other ContinuationInterceptor, then Dispatchers.Default is used.

这意味着如果您不将调度程序传递给 launch,它将默认为您启动 CoroutineScope 上下文中存在的调度程序 启动。如果协程上下文没有调度程序,then launch 将使用 Dispatchers.Default

因此,在您的情况下,无参数 launch 继承了上下文,因此继承了 runBlocking 提供的调度程序,这是一个在它阻塞的线程上运行的单线程调度程序(这里是主线程)。

why does launch(Dispatchers.Default) allow the second coroutine to start and why doesn't just launch ?

这是因为,正如我们刚刚看到的,这两种情况不涉及相同的线程。使用 launch(Dispatchers.Default),启动的协程在单独的线程池上运行,并且可以与主协程并行运行。但是,使用无参数launch,第二个协程与其余代码运行在同一个线程上,因为它运行在runBlocking 的单线程调度程序中,即由主线程支持。

最后一 block 拼图是 Thread.sleep阻塞(如您所说),与 delay 不同,delay 是挂起的等价物来自协程库。当只涉及一个线程时(在无参数 launch 的情况下),运行最后一个 Thread.sleep 会阻塞主线程并且永远不会给其他协程机会运行。您需要一些东西来暂停执行,例如 delay()

关于Kotlin 启动与启动(Dispatchers.Default),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/74327119/

相关文章:

android - 在 Android Kotlin 的 WebView 中加载网站 URL 之前先 Ping 网站 URL

kotlin - Kotlin/JS 中不提供依赖项

kotlin - kotlin-react useEffect中如何订阅StateFlow

android - 处理 Kotlin Coroutines 中自定义 okhttp 拦截器引发的异常

android - 在 kotlin 中带有微调器的 ArrayAdapter - 不能使用提供的参数调用以下函数

kotlin - 如何从 kotlin 中的数据类访问 val?

android - 在 Activity 的 init block 中使用 'this' 作为上下文?

kotlin - 使用 webflux 进行上下文日志记录( header 中的相关 ID)

java - 正确使用协程

android - Kotlin Coroutine Retrofit - 链式网络调用