Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/kotlin/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
为什么“等待”会阻止kotlin中的线程?_Kotlin_Async Await - Fatal编程技术网

为什么“等待”会阻止kotlin中的线程?

为什么“等待”会阻止kotlin中的线程?,kotlin,async-await,Kotlin,Async Await,“等待”的api说明: 在不阻塞线程的情况下等待此值的完成,并在延迟计算完成时恢复,返回结果值或在延迟计算被取消时引发相应的异常 结果: 开始->1575977567 结束->157597570 “开始”和“结束”之间有三秒钟的间隔。因此这行“one.await”阻塞了线程。为什么它与api所说的不同。它不一定会阻塞线程。从传递给runBlocking{…}的lambda构建的协同路由的执行在one.await挂起,然后在一个结果就绪后恢复。在此期间,执行协程的线程可以切换到执行另一个协程(如果

“等待”的api说明:

在不阻塞线程的情况下等待此值的完成,并在延迟计算完成时恢复,返回结果值或在延迟计算被取消时引发相应的异常

结果:

开始->1575977567

结束->157597570

“开始”和“结束”之间有三秒钟的间隔。因此这行“one.await”阻塞了线程。为什么它与api所说的不同。

它不一定会阻塞线程。从传递给runBlocking{…}的lambda构建的协同路由的执行在one.await挂起,然后在一个结果就绪后恢复。在此期间,执行协程的线程可以切换到执行另一个协程(如果有的话)。但这不是因为,通过调用runBlocking{…},您明确指定要在当前单个线程中运行协同路由,在协同路由完成之前独占使用该线程,从而在协同路由挂起且没有其他协同路由可运行时阻塞该线程

例如,如果在testAsyncAwait函数中添加第二对async{…}+await,那么await调用实际上将并发执行

您还可以使用另一个显式支持运行多个协同路由的调度程序来运行此协同路由,您将看到在这种情况下one.await调用不会阻塞线程

例如,您可以按如下方式运行:

suspend fun doSomethingUsefulOne(): Int {
    delay(3000L)
    return 13
}

suspend fun testAsyncAwait(n: Int) = coroutineScope {
    val one = async { doSomethingUsefulOne() }
    println("start $n ->" + System.currentTimeMillis() / 1000)
    one.await()
    println("end $n ->" + System.currentTimeMillis() / 1000)
}

suspend fun main() = coroutineScope {
    val context = newSingleThreadContext("MyOwnThread")
    repeat(2) {
        launch(context) { testAsyncAwait(it) }
    }
}
两个协程将同时运行,一个.await不应阻止单个线程:

start 0 -> 1575982105
start 1 -> 1575982106
end 0 -> 1575982109
end 1 -> 1575982109
请参见语言参考中的以下章节:

它不一定会阻塞线程。从传递给runBlocking{…}的lambda构建的协同路由的执行在one.await挂起,然后在一个结果就绪后恢复。在此期间,执行协程的线程可以切换到执行另一个协程(如果有的话)。但这不是因为,通过调用runBlocking{…},您明确指定要在当前单个线程中运行协同路由,在协同路由完成之前独占使用该线程,从而在协同路由挂起且没有其他协同路由可运行时阻塞该线程

例如,如果在testAsyncAwait函数中添加第二对async{…}+await,那么await调用实际上将并发执行

您还可以使用另一个显式支持运行多个协同路由的调度程序来运行此协同路由,您将看到在这种情况下one.await调用不会阻塞线程

例如,您可以按如下方式运行:

suspend fun doSomethingUsefulOne(): Int {
    delay(3000L)
    return 13
}

suspend fun testAsyncAwait(n: Int) = coroutineScope {
    val one = async { doSomethingUsefulOne() }
    println("start $n ->" + System.currentTimeMillis() / 1000)
    one.await()
    println("end $n ->" + System.currentTimeMillis() / 1000)
}

suspend fun main() = coroutineScope {
    val context = newSingleThreadContext("MyOwnThread")
    repeat(2) {
        launch(context) { testAsyncAwait(it) }
    }
}
两个协程将同时运行,一个.await不应阻止单个线程:

start 0 -> 1575982105
start 1 -> 1575982106
end 0 -> 1575982109
end 1 -> 1575982109
请参见语言参考中的以下章节:

delay3000延迟3秒-这必须起作用,所以您希望在输出之间看到3秒

然而,在这3秒钟内,线程不会被wait阻塞。它被runBlocking阻止,因为它正在等待您的协同程序完成。如果您在runBlocking内部启动了其他非同步协同程序,那么它们可以在这段时间内执行。

延迟3000次延迟3秒-这必须起作用,因此您希望在输出之间看到3秒的间隔

然而,在这3秒钟内,线程不会被wait阻塞。它被runBlocking阻止,因为它正在等待您的协同程序完成。如果您在runBlocking内部启动了其他非同步协程,那么它们可以在此期间执行。

线程未被阻塞。请参阅线程未被阻塞。看见