为什么Kotlin忽略了延迟(timeMillis:Long)函数 上下文
遵循Kotlin协作路线基础指南 使用此代码为什么Kotlin忽略了延迟(timeMillis:Long)函数 上下文,kotlin,concurrency,kotlin-coroutines,Kotlin,Concurrency,Kotlin Coroutines,遵循Kotlin协作路线基础指南 使用此代码 fun coroutinesAreLightWeight() { runBlocking { repeat(100_000) { launch { delay(1000L) print("$it, ") } } } } 问题 当我在我的电脑上运行程序时,它会一次性打印出所有数字,而不是等待1
fun coroutinesAreLightWeight()
{
runBlocking {
repeat(100_000) {
launch {
delay(1000L)
print("$it, ")
}
}
}
}
问题
当我在我的电脑上运行程序时,它会一次性打印出所有数字,而不是等待1秒后再打印下一个数字。当运行kotlin指南中所示的精确代码时,这种行为是相同的。似乎正在忽略delay()
函数
起初,这段代码运行良好,但后来它停止了预期的工作。我正在将IntelliJ 2019.2.1与kotlin版本1.3.50一起使用,我尝试重新启动该程序,但这并没有解决我的问题
下面是整个班级的样子
class CoroutinesBasics
{
fun ...
fun ...
fun coroutinesAreLightWeight()
{
runBlocking {
repeat(100_000) {
launch {
delay(1000L)
print("$it, ")
}
}
}
}
}
而coroutinesAreLightWeight()
函数的调用方式如下
fun main()
{
CoroutineBasics().apply{
....
....
coroutinesAreLightWeight()
}
}
有人能告诉我发生了什么事吗?这是科特林虫吗
Kotlin依赖项
implementation'org.jetbrains.kotlinx:kotlinx coroutines core:1.3.0'
据我所知,这是预期的行为,因为coroutines同时工作,所以您的代码将只等待1秒,等待当前正在工作的所有coroutines
我推荐的一个关于协作的好话题是:
幻灯片中的示例与此完全相同:)
如果您想让他们等待,您应该将repeat移到“runBlocking”之外。据我所知,这是预期的行为,因为协同路由同时工作,所以对于当前正在工作的所有协同路由,您的代码将只等待1秒 我推荐的一个关于协作的好话题是: 幻灯片中的示例与此完全相同:)
如果您想让他们等待,您应该将重复移动到“运行阻塞”之外。我将从另一个角度回答这个问题。
该示例是在特定上下文中给出的。也就是说,“协同程序不像线程”。本示例的目标不是演示如何延迟打印数字,而是演示与线程不同的协同路由可以同时启动数千次。这正是这段代码所做的。它提交它们,然后执行它们 你可能会问,为什么它们都是顺序的?它们不应该同时运行吗?
为此,让我们打印线程名称:
repeat(100_000) {
launch {
delay(100L)
println("$it, ${Thread.currentThread().name}")
}
}
您将很快看到原因:99999,main
由于您使用的是运行阻塞
,因此所有协同程序都由一个线程执行
但我们可以改变它:
runBlocking {
repeat(100_000) {
launch(Dispatchers.Default) {
delay(100L)
println("$it, ${Thread.currentThread().name}")
}
}
}
通过使用Dispatchers.Default
,我们在一个默认线程池上运行我们的协同程序。结果变得不那么可预测:
98483, DefaultDispatcher-worker-6
99898, DefaultDispatcher-worker-5
99855, DefaultDispatcher-worker-1
99706, DefaultDispatcher-worker-2
默认的线程池从2个线程开始,默认情况下增加到CPU核心数。您可以查看createDefaultDispatcher()
了解实际实现
关于Thread.sleep()
,您应该知道一些事情:
Thread.sleep()
Thread.sleep()
Thread.sleep()
repeat(100_000) {
launch {
Thread.sleep(100)
println("$it, ${Thread.currentThread().name}")
}
}
你可以假设你说的是“在100毫秒内不要在这个区块内做任何事情”
但实际上你说的是“100毫秒内不要做任何事情”
由于
launch
将在它从runBlocking
获得的上下文上执行,并且runBlocking
是一个单线程上下文,因此您将阻止所有协程的执行。我将从另一个角度来回答这个问题。该示例是在特定上下文中给出的。也就是说,“协同程序不像线程”。本示例的目标不是演示如何延迟打印数字,而是演示与线程不同的协同路由可以同时启动数千次。这正是这段代码所做的。它提交它们,然后执行它们 你可能会问,为什么它们都是顺序的?它们不应该同时运行吗?
为此,让我们打印线程名称:
repeat(100_000) {
launch {
delay(100L)
println("$it, ${Thread.currentThread().name}")
}
}
您将很快看到原因:99999,main
由于您使用的是运行阻塞
,因此所有协同程序都由一个线程执行
但我们可以改变它:
runBlocking {
repeat(100_000) {
launch(Dispatchers.Default) {
delay(100L)
println("$it, ${Thread.currentThread().name}")
}
}
}
通过使用Dispatchers.Default
,我们在一个默认线程池上运行我们的协同程序。结果变得不那么可预测:
98483, DefaultDispatcher-worker-6
99898, DefaultDispatcher-worker-5
99855, DefaultDispatcher-worker-1
99706, DefaultDispatcher-worker-2
默认的线程池从2个线程开始,默认情况下增加到CPU核心数。您可以查看createDefaultDispatcher()
了解实际实现
关于Thread.sleep()
,您应该知道一些事情:
Thread.sleep()
Thread.sleep()
Thread.sleep()
repeat(100_000) {
launch {
Thread.sleep(100)
println("$it, ${Thread.currentThread().name}")
}
}
你可以假设你说的是“在100毫秒内不要在这个区块内做任何事情”
但实际上你说的是“100毫秒内不要做任何事情”
由于
launch
将在它从runBlocking
获得的上下文上执行,并且runBlocking
是一个单线程上下文,因此您可以阻止所有协同程序的执行。但是根据Kotlin协同程序指南,它的内容是“它启动100K个协同程序,一秒钟后,每个协同程序打印一个点。”你能在runBlocking{repeat(100_000)之前打印一些东西吗{
或者将延迟时间增加10秒,这样你就可以知道它是否正在等待。你的代码将发生什么:它将为你创建100000个协程,每个协程将等待1秒,然后打印。因此,在一秒钟后,你将有100000个打印。因为该块中的所有代码将同时工作,因为delay
和线程.sleep<