首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >在db调用时调用Await.result有多大的风险?

在db调用时调用Await.result有多大的风险?
EN

Stack Overflow用户
提问于 2016-11-24 22:08:08
回答 1查看 1.1K关注 0票数 2

在使用幻影时,在db调用中遵循这种模式有多危险:

代码语言:javascript
运行
复制
Await.result(dbOperationFut, 30.seconds)

这并不是幻影特有的,但它是正在使用的scala驱动程序。

我对这种模式感到厌倦,因为可能会持续超过x秒钟的GC暂停。如果GC暂停,安全的时间是多少秒?

我个人支持使用for-comp,而不是像这样阻塞,但我只想知道这是一个真的不好的做法,还是它是好的。

上下文:这将适用于基于akka的应用程序( akka,akka http)

有什么想法?

EN

Stack Overflow用户

回答已采纳

发布于 2016-11-25 09:52:15

与Await.result保持一致

注意,这适用于Akka和play应用程序。

只有在绝对必要时,才应该非常小心地使用Await.result

Await.result阻塞它正在运行的线程,直到给定持续时间为止。阻塞线程将浪费宝贵的计算资源,因为该线程将无法进行任何有用的计算,例如处理新的请求或在算法中进行数字处理等。

因此,尽量避免使用Await.result

但是,我们什么时候使用它(Await.result)?

下面是使用Await.result的典型用例之一。

假设您已经编写了一个包含主线程的程序,并且主线程中的所有计算都是异步的。现在,在主线程中启动异步计算之后。有些人必须停止主线程的存在,直到异步计算完成,如果程序不停止运行,您将看不到异步计算的结果。

当应用程序开始运行时,有一个非守护进程线程,其任务是执行main()。除非完成非守护进程线程,否则JVM不会自行退出。

代码语言:javascript
运行
复制
object Main {
 def main(args: Array[String]): Unit = {
  import scala.concurrent.Future
  import scala.concurrent.duration._

  val f = Future { //do something }
  //stop main thread till f completes
  Await.result(f, 10 seconds)
 }
}

未来将使用守护进程线程来运行。因此守护进程线程不能阻止JVM关闭。因此,即使非守护进程线程正在运行,JVM也会关闭。

在上述情况下,在计算f完成之前,没有其他方法可以期望停止(阻塞)主线程,如果主线程没有退出,则计算停止。

在大多数情况下,您不需要使用Await.result,使用mapflatMap进行简单的Future组合就足够了。

使用(一般为所有阻塞代码)的风险

基于事件的模型中线程的耗尽

在基于事件的模型中,如果阻塞代码需要很长时间才能返回,那么线程就会很快用完。在游戏框架中,任何阻塞调用都会降低应用程序的性能,并且当应用程序耗尽线程时会变得非常慢。

在非事件模型中内存不足

在每个请求模型的线程中。当您有阻塞呼叫时,需要很长时间才能退出/返回。

案例1:如果您有固定的线程池,那么应用程序可能会耗尽线程。

案例2:如果您有动态增长的线程池,那么您的应用程序将遭受太多的上下文切换开销,并且由于内存中阻塞的线程太多,也会耗尽内存。

在所有情况下,对于等待某个IO或其他事件,都没有做任何有用的工作。

票数 4
EN
查看全部 1 条回答
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/40795109

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档