Is delay() In Kotlin Coroutine a non-blocking function?
示例代码中的注释说delay()是非阻塞的。 应该暂停吗?
https://kotlinlang.org/docs/reference/coroutines/basics.html
1 2 3 4 5 6 7 8
| 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
} |
-
这是正确的描述,因为它不阻塞任何线程,而只是挂起当前的协程。
-
非阻塞是计算机科学中定义明确的术语。根据定义,println(" World!")将立即运行,而不是等待1秒钟。如果您的意思不同,请不要使用此术语。
-
我的意思绝对没有不同,我看不出您想说什么。就像我刚才解释的那样,延迟不是阻塞电话。
-
@Moira:延迟正在暂停且未阻塞。乔佛里已经回答了。它不仅是"非阻塞"的。
-
@Moira:正如您所说,"它只是暂停当前的协程"。为什么对延迟电话的评论不这样说?而是,注释为"非阻塞"。这不是误导吗?
-
不。您需要了解协程本质上是美化的回调(并以此方式进行编译。)计划在2000毫秒内执行的回调不会阻塞任何线程,例如,与Thread.sleep不同(因此它是非阻塞的),它只是"暂停"协程。暂停当前??协程的执行,直到达到悬浮点为止。协程与线程并不相同,即使最终结果相似,文档也不会适当地将它们视作线程。
Kotlin文档经常对挂起函数说"非阻塞",以表明它们不会阻塞当前线程,而只是挂起当前协程。
是的,delay正在挂起且未阻塞。
有时可能会产生误导,因为"非阻塞"强调没有阻塞的事实,同时仍应明确指出,挂起函数确实会挂起当前的协程(因此至少有一些被阻塞,即使线程 本身进行下去)。
它们暂停当前协程的事实使这些功能从当前协程的角度来看是同步的,因为协程需要在执行其余代码之前等待这些功能完成。 但是,它们实际上并没有阻塞当前线程,因为它们的实现在幕后使用了异步机制。
-
谢谢!您的回答是合理的。这里的"非阻塞"确实令人误解。正式文件不应将此定义明确的术语用于其他用途。协程是一个新功能。值得定义一组新术语来解释这些功能。
-
@ user1443721 FWIW这个术语对于异步编程不是什么新知识。例如,请参阅C#文档。
-
@ user1443721那正是Kotiln所做的。新术语是"挂起",而旧术语("阻塞")保留了旧含义,仍然指线程。
-
@Moira:非阻塞已经定义得很好,甚至早于C#。检查此问题的答案,stackoverflow.com / questions / 10570246 /
-
@Marko Topolnik:"挂起"不是新术语。它已用于描述线程生命周期。我的问题主要是在示例中对delay()函数的注释。
-
@ user1443721正是我的意思。非阻塞已经使用了很长时间(尤其是在异步操作的上下文中)。
-
@ user1443721在JVM内部,方法Thread.suspend()使用"挂起",该方法从未实现,至今已弃用20年。我认为您将能够习惯于协程的含义,而不会与不存在的线程挂起混淆。无论是我还是我见过的任何人都没有提出过歧义的顾虑。而且,每种语言/环境都使用相同的术语,但含义略有不同,这是众所周知的现象。在每种环境中发明新词并不常见。
-
@Marko Topolnik:您承认该术语含糊不清。写下更清晰的评论以帮助读者理解更好吗?示例是基本类别中的"您的第一个协程"。这意味着读者是协程的初学者。
-
@Moira:但是您必须意识到"非阻塞"没有意义"挂起"。这就是我想说的。
-
@ user1443721您是正确的,但是该函数是一个暂停函数,因此我想这将是多余的。我没有写文档,但是我认为这与调用延迟的结果很明显的事实相结合,导致在文档中没有提及。
-
@Moira:再次,这是"您的第一个协程"。读者不知道什么是" delay()"。
-
@Marko Topolnik:不需要Thread.suspend()。阻塞的线程处于挂起状态。 Java还有另一个方法yield(),它也可以发送要暂停的线程。
-
@ user1443721我想现在您在OS抢先式多任务处理级别上谈论任务挂起,因此您使用的是完全不同的参考框架。但是,当OS抢占运行给定Java线程的本机线程时,Java线程状态仍为RUNNABLE。