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



我有来自这段代码的问题。

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
}

我将delay(1000L)替换为Thread.sleep(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
} 

GlobalScope允许您启动或多或少与守护程序线程具有相同行为的协程,因为它们与任何协程Job分离,并且基本上与应用程序一样长。它们的生命周期仅受应用程序本身的限制。这是您希望通过使用"结构化并发"来避免的事情,这基本上意味着您的协程应该以一种可以控制它们的方式嵌套,而无需手动跟踪它们的引用并加入它们,例如为了等待它们的计算。因此,在现实生活中的代码中,您应该尽可能避免GlobalScope,因为肯定有更好的解决方案。

至于您的问题,如前所述,GlobalScopeDispatchers.Default池上运行,这意味着您将阻止某个工作线程,但不会阻止您从中生成协程的工作线程。

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

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

您将看到协程阻止main线程,输出将显示不同的结果。这是因为runBlocking在调用方线程main上运行,而不是在工作线程池线程上运行。

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

在有关调度程序和线程的文档中,您将找到以下内容:

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

在 Dispatchers.Default 文档中,您可以找到:

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

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

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

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

您将需要运行更多协程才能看到它们由于Thread.sleep调用而相互阻止。

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

相关内容

  • 没有找到相关文章

最新更新