GlobalScope.launch是创建新线程还是在同一线程中运行?

时间:2019-03-25 22:27:23

标签: kotlin kotlin-coroutines

我对这段代码有疑问。

https://kotlinlang.org/docs/reference/coroutines/basics.html

fun main() {
    GlobalScope.launch { // launch new coroutine in background and continue
        delay(1000L) // non-blocking delay for 1 second (default time unit is ms)
        println("World!") // print after delay
    }
    println("Hello,") // main thread continues while coroutine is delayed
    Thread.sleep(2000L) // block main thread for 2 seconds to keep JVM alive
}

我用Thread.sleep(1000L)替换了delay(1000L)。如果GlobalScope.launch块将在同一线程中运行,则Thread.sleep(1000L)将阻塞该线程。但是似乎没有。

fun main() {
    GlobalScope.launch { // launch new coroutine in background and continue
        Thread.sleep(1000L)
        println("World!")
    }
    println("Hello,") // 
    Thread.sleep(2000L) // block main thread for 2 seconds to keep JVM alive
} 

3 个答案:

答案 0 :(得分:1)

GlobalScope使您可以启动协程,它们与daemon threads几乎具有相同的行为,因为它们与任何协程-Job分离并且基本上在应用程序中运行。它们的生命周期仅受应用程序本身的限制。您想通过使用“ structured concurrency”来避免这种情况,这基本上意味着您的协程应该以一种可以嵌套的方式进行控制,而无需手动跟踪它们的引用并加入它们,例如等待它们计算。因此,在现实生活中的代码中,应尽可能避免使用GlobalScope,因为肯定有更好的解决方案。

关于您的问题,并且如上所述,GlobalScopeDispatchers.Default池上运行,这意味着您将阻止一些工作线程,但不会阻塞您从那里产生协程。

另一方面,如果要编写此块:

fun main() {
    runBlocking { 
        Thread.sleep(1000L) 
        println("World!") 
    }
    println("Hello,") 
    Thread.sleep(2000L) 
}

您将看到协程阻塞了main线程,并且输出将显示不同的结果。这是因为runBlocking运行在调用者线程main上,而不是在工作池线程之一上运行。

答案 1 :(得分:0)

GlobalScope.launch { }不一定 create 一个新线程,但是它将使用共享池中的一个线程,因为它使用了Default调度程序。因此,就您的问题而言,在您的代码段中,传递给启动的代码块确实在另一个线程中运行。

在有关dispatchers and threads的文档中,您将找到以下内容:

  

在GlobalScope中启动协程时使用的默认调度程序由Dispatchers表示。默认值并使用共享的后台线程池

Dispatchers.Default doc中,您可以找到:

  

默认情况下,此调度程序使用的最大并行度等于CPU内核数,但至少为两个。并行级别X保证在此调度程序中可以并行执行最多X个任务。

请注意,您可以通过提供一个作为launch的参数来更改调度程序。

答案 2 :(得分:0)

GlobalScope.launch{..}函数不会阻塞。它返回一个Job对象,您可以使用它来等待结果。

在幕后,GlobalScope使用默认的调度程序Dispatchers.Default。您可能会看到它,例如,通过在launch{..}函数内部打印线程名称。

您将需要运行更多协程,以查看它们由于Thread.sleep调用而相互阻塞。

https://kotlinlang.org/docs/reference/coroutines/coroutine-context-and-dispatchers.html