我对这段代码有疑问。
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
}
答案 0 :(得分:1)
GlobalScope
使您可以启动协程,它们与daemon threads几乎具有相同的行为,因为它们与任何协程-Job
分离并且基本上在应用程序中运行。它们的生命周期仅受应用程序本身的限制。您想通过使用“ structured concurrency”来避免这种情况,这基本上意味着您的协程应该以一种可以嵌套的方式进行控制,而无需手动跟踪它们的引用并加入它们,例如等待它们计算。因此,在现实生活中的代码中,应尽可能避免使用GlobalScope
,因为肯定有更好的解决方案。
关于您的问题,并且如上所述,GlobalScope
在Dispatchers.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