Jav*_*ide 3 concurrency kotlin spring-boot kotlin-coroutines
给定一个 REST 端点和两个异步协程,每个异步协程返回一个整数,我希望该端点返回它们的总和。这两个函数(funA 和 funB)应该并行运行,这样整个计算大约需要 3 秒。我正在使用 SpringBoot 2.6.3 和 Kotlin Coroutines 1.6.0。这是我的尝试:
import kotlinx.coroutines.*
import kotlinx.coroutines.flow.*
import org.springframework.web.bind.annotation.GetMapping
import org.springframework.web.bind.annotation.RestController
@RestController
class Controllers {
@GetMapping(
value = ["/summing"]
)
fun summing(): String {
val finalResult = runBlocking {
val result = async { sum() }
println("Your result: ${result.await()}")
return@runBlocking result
}
println("Final Result: $finalResult")
return "$finalResult"
}
suspend fun funA(): Int {
delay(3000)
return 10
}
suspend fun funB(): Int {
delay(2000)
return 90
}
fun sum() = runBlocking {
val resultSum = async { funA().await() + funB().await() }
return@runBlocking resultSum
}
}
Run Code Online (Sandbox Code Playgroud)
问题是该代码无法编译,因为 wait() 未被识别为有效方法。如果我删除await(),这两个函数将连续执行(总时间约为5秒),而不是预期的结果(100),我得到:
Your result: DeferredCoroutine{Completed}@1c1fe804
Final Result: DeferredCoroutine{Completed}@48a622de
Run Code Online (Sandbox Code Playgroud)
因此端点返回“DeferredCoroutine{Completed}@48a622de”。
我希望端点在大约 3 秒内返回“100”。我怎样才能实现这个目标?
你真的搞砸了;-)你的代码有几个问题:
runBlocking()
使用runBlocking()
其中的另一个。async()
并立即调用await()
它(在summing()
) - 它什么也不做。funA().await()
确实没有funB().await()
任何意义。这些函数返回整数,但不能await()
返回已获取的整数。解决方案非常简单:使用runBlocking()
一次跳转到协程世界,然后使用async()
同时启动两个函数:
runBlocking {
val a = async { funA() }
val b = async { funB() }
a.await() + b.await()
}
Run Code Online (Sandbox Code Playgroud)
或者:
runBlocking {
listOf(
async { funA() },
async { funB() },
).awaitAll().sum()
}
Run Code Online (Sandbox Code Playgroud)
或者(稍微短一些,但我认为可读性较差):
runBlocking {
val a = async { funA() }
funB() + a.await()
}
Run Code Online (Sandbox Code Playgroud)
而且,runBlocking()
也并不理想。我相信 Spring 支持协程,因此最好使用summing()
函数suspend
并使用coroutineScope()
它runBlocking()
,这样代码就不会阻塞任何线程。
归档时间: |
|
查看次数: |
2317 次 |
最近记录: |