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

Kotlin GlobalScope.launch是创建新线程还是在同一线程中运行?,kotlin,kotlin-coroutines,Kotlin,Kotlin Coroutines,我有这个密码的问题 我用Thread.sleep(1000L)替换延迟(1000L)。如果GlobalScope.launch块将在同一线程中运行,则thread.sleep(1000L)将阻塞该线程。然而,似乎并非如此 fun main() { GlobalScope.launch { // launch new coroutine in background and continue Thread.sleep(1000L) println("Worl

我有这个密码的问题

我用Thread.sleep(1000L)替换延迟(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.launch{}
不一定会创建新线程,但它会使用共享池中的线程,因为它使用
默认调度程序。因此,就您的问题而言,在您的代码片段中,传递给launch的块实际上运行在不同的线程中

在关于的文档中,您将发现以下内容:

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

在中,您可以找到:

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


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

的参数来更改调度程序
GlobalScope.launch{..}
函数将不会阻塞。它返回一个
作业
对象,可用于等待结果

在幕后,
GlobalScope
使用默认的dispatcher
Dispatchers.default
。例如,您可以通过在
launch{..}
函数中打印线程名称来查看它

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


使用
GlobalScope
可以启动协同程序,因为它们与任何协同程序-
作业
分离,基本上只要应用程序运行就可以运行。它们的生命周期仅受应用程序本身的限制。这是您希望通过使用“”来避免的,这基本上意味着您的协同程序应该嵌套在一种您可以控制它们的方式中,而无需手动跟踪它们的引用并连接它们,例如为了等待它们的计算。因此,在您的实际代码中,您应该尽可能避免使用
GlobalScope
,因为肯定有更好的解决方案

至于您的问题,正如前面提到的,
GlobalScope
Dispatchers.Default
池上运行,这意味着您将阻止一些工作线程,而不是从中生成协同程序的线程

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

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

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

“但它将使用共享池中的一个线程”。如果CPU至少有2个内核,是否意味着GlobalScope.launch{}在另一个线程中运行?不是这样。事实上,该池至少包含2个线程,即使对于单个代码处理器也是如此。如果我理解正确的话,那就是医生说的。找到了。在这两个示例中,GlobalScope.launch在不同的线程中运行。
fun main() {
    runBlocking { 
        Thread.sleep(1000L) 
        println("World!") 
    }
    println("Hello,") 
    Thread.sleep(2000L) 
}