gpt4 book ai didi

java - Scala 和 Java 的 future 显然有意想不到的互动

转载 作者:塔克拉玛干 更新时间:2023-11-03 03:25:02 25 4
gpt4 key购买 nike

我们在 Scala Play Framework 应用程序中使用 Elasticsearch 0.90.7,其中“doSearch”方法的结尾如下所示:

def doSearch(...) = {
...
val actionRequessBuilder: ActionRequestBuilder // constructed earlier in the method
val executedFuture: ListenableActionFuture<Response> = actionRequestBuilder.execute
return executedFuture.actionGet
}

其中 ListenableActionFuture extends java.util.concurrent.FutureListenableActionFuture#actionGetFuture#get 基本相同

当我们按顺序执行搜索时,一切正常,但是当我们尝试并行执行多个搜索时:

val search1 = scala.concurrent.Future(doSearch(...))
val search2 = scala.concurrent.Future(doSearch(...))
return Await.result(search1, defaultDuration) -> Await.result(search2, defaultDuration))

我们有时(不到 1% 或 2% 的时间)在我们的 scala future 上遇到意外超时,即使在 qa 期间使用极长的超时(5 秒,搜索总是在不到 200 毫秒内执行)。在使用 scala 全局执行上下文以及使用 Play 默认执行上下文时也会发生这种情况。

由于将 java future 包装在 scala future 中,这里是否发生了某种意想不到的交互?我原以为 actionGetdoSearch 结束时调用 java future 会阻止两个 future 相互干扰,但显然这可能不是案例。

最佳答案

我认为阻止是邪恶的某处成立。邪恶!

在这种情况下,Await.result 将阻塞当前线程,因为它正在等待结果。

Await 将调用包装在 blocking 中,试图通知线程池它可能想要增加一些线程以维持其所需的并行度并避免死锁。

如果当前线程不是 Scala BlockContext,那么您只会遇到阻塞。

无论您的精确配置如何,大概是您在阻塞时保持线程,并且您正在运行搜索的 thunk 想要运行某些东西但不能因为池已耗尽。

相关的是哪个池产生了当前线程:中间人 Future 是否在不同的池上并不重要,如果在底部,您需要使用当前池中的更多线程并且它已耗尽。

当然,这只是一个猜测。

拥有一个从两次搜索中获取值(value)并带有超时的 future 更有意义。

但是,如果您最终拥有多个 Future,则使用 Future.sequence 并等待它是有意义的。

关于java - Scala 和 Java 的 future 显然有意想不到的互动,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/22457573/

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