gpt4 book ai didi

spring-mvc - 除非使用GobalScope调用,否则将依次调用kotlin异步调用

转载 作者:行者123 更新时间:2023-12-02 13:31:44 24 4
gpt4 key购买 nike

好的,所以我有一个 Controller 方法,该方法需要对外部服务进行大量肥皂调用,每个调用都非常繁重。我试图并行执行这些操作以节省一些时间,但是除非我从GlobalScope构建async调用,否则将按顺序解决延迟的操作。让我给你演示。

执行以下代码

@ResponseBody
@GetMapping(path = ["/buildSoapCall"])
fun searchStations(): String = runBlocking {

var travels: List<Travel> = service.getTravels().take(500)
val deferred = travels
.map {
async() {
print("START")
val result = service.executeSoapCall(it)
print("END")
result
}
}
println("Finished deferred")
val callResults = deferred.awaitAll()
println("Finished Awaiting")

""
}

得到以下控制台消息:
Finished deferred
START-ENDSTART-ENDSTART-ENDSTART-ENDSTART-ENDSTART-ENDSTART-ENDSTART-ENDSTART-ENDSTART-ENDSTART-ENDSTART-ENDSTART-ENDSTART-ENDSTART-ENDSTART-ENDSTART-ENDSTART-ENDSTART-ENDSTART-ENDSTART-ENDSTART-ENDSTART-ENDSTART-ENDSTART-ENDSTART-ENDSTART-ENDSTART-ENDSTART-ENDSTART-END.....
-executeSoapCall打印

如您所见,延期被依次调用。

但是,如果我使用 GlobalScope,像这样:

@ResponseBody
@GetMapping(path = ["/buildSoapCall"])
fun searchStations(): String = runBlocking {

var travels: List<Travel> = service.getTravels().take(500)
val deferred = travels
.map {
GlobalScope.async() {
print("START")
val result = service.executeSoapCall(it)
print("END")
result
}
}
println("Finished deferred")
val callResults = deferred.awaitAll()
println("Finished Awaiting")

""
}

我收到以下控制台消息:
Finished Treating 
STARTSTARTSTARTSTARTSTARTSTARTSTARTSTARTSTARTSTARTSTARTFinished deferred
START-ENDSTART-ENDSTART-ENDSTART-ENDSTART-ENDSTART-ENDSTART-ENDSTART-ENDSTART-ENDSTART-ENDSTART-ENDSTART-ENDSTART-ENDSTART-ENDSTART-ENDSTART--ENDENDSTARTSTART-ENDSTART-ENDSTART-ENDSTART-ENDSTART-ENDSTART-ENDSTART-ENDSTART-ENDSTART-ENDSTART-ENDSTART-ENDSTART-ENDSTART-ENDSTART-ENDSTART-ENDSTART-ENDSTART-ENDSTART-ENDSTART-ENDSTART-ENDSTART-ENDSTART-ENDSTART-ENDSTART-ENDSTART-ENDSTART-END...START-END-END-END-END-END-END-END-END-END-END-END-ENDFinished Awaiting

表示“延期”都是并行开始的。另外,治疗时间相当短。

我真的不明白为什么我会有这种行为。

最佳答案

您对service.executeSoapCall的调用会阻止正在运行runBlocking协程的线程。您需要每次在不同的线程上启动async协程以获得并发行为。您可以使用线程池来实现这一点,例如Dispatchers.IO:

...
async(Dispatchers.IO) {
print("START")
val result = service.executeSoapCall(it)
print("END")
result
}
...

或在每次调用时创建一个新线程:
...
async(newSingleThreadContext("MyThread")) {
print("START")
val result = service.executeSoapCall(it)
print("END")
result
}
...
GlobalScope之所以有效,是因为它默认情况下使用ThreadPool,但您应避免使用它。您可以通过 this article阅读有关该主题的 Roman Elizarov

关于spring-mvc - 除非使用GobalScope调用,否则将依次调用kotlin异步调用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/60889941/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com