在协程中使用runBlocking会发生什么不好的事情吗?

时间:2019-12-30 11:19:54

标签: kotlin coroutine kotlin-coroutines

the documentation of runBlocking中可以清楚地看出,从协程中使用它(例如将其嵌套)为什么没有意义。

它甚至明确指出:

  

不应在协程中使用此功能。

但是,可以这样做:

fun main(args: Array<String>) {
    runBlocking {
        runBlocking {
            println("hi")
        }
    }
}

(IntelliJ)IDE有点抱怨

OCvdVKx

但是代码可以编译并运行。

在更复杂的环境中意外完成时会发生什么?崩溃了吗?还是死锁?

2 个答案:

答案 0 :(得分:3)

  

在更复杂的环境中意外完成时会发生什么?崩溃了吗?还是死锁?

不,没有类似的东西。实际上,app.js是专门为支持嵌套而编写的:

  

如果指定的调度程序是另一个runBlocking的事件循环,则此调用使用外部事件循环。

您提到的问题实际上与嵌套runBlocking调用无关,而是从协程调用任何阻塞代码的总体问题。我们使用协程的特定目的是避免阻塞线程,因此在其中调用阻塞函数通常是错误的。您将收到runBlockingThread.sleep()通话等相同的警告。

答案 1 :(得分:-2)

这完全取决于您要阻塞的线程。有时,您可能需要阻塞线程才能完成某些工作,然后在后台启动另一工作。

例如,只要您不阻止Android中的主(UI)线程,就可以阻止其他线程。但是您必须知道并知道该线程何时被阻塞,因此您不必立即执行需要该线程提供某些信息的操作。

假设您有一个线程下载并对照片应用滤镜。这是在后台线程上完成的,而不是在主线程上完成的。您可以开始执行所有这些操作的新协程。但是下载部分应该在runBlocking线程内完成,因为您需要先下载,然后将滤镜应用于照片。您不能同时访问这些内容。

总而言之,有时候,您实际上需要使用runBlocking。并且,如果使用正确,您将不会崩溃。