在使用幻影时,在db调用中遵循这种模式有多危险:
Await.result(dbOperationFut, 30.seconds)这并不是幻影特有的,但它是正在使用的scala驱动程序。
我对这种模式感到厌倦,因为可能会持续超过x秒钟的GC暂停。如果GC暂停,安全的时间是多少秒?
我个人支持使用for-comp,而不是像这样阻塞,但我只想知道这是一个真的不好的做法,还是它是好的。
上下文:这将适用于基于akka的应用程序( akka,akka http)
有什么想法?
发布于 2016-11-25 09:52:15
与Await.result保持一致
注意,这适用于Akka和play应用程序。
只有在绝对必要时,才应该非常小心地使用
Await.result。
Await.result阻塞它正在运行的线程,直到给定持续时间为止。阻塞线程将浪费宝贵的计算资源,因为该线程将无法进行任何有用的计算,例如处理新的请求或在算法中进行数字处理等。
因此,尽量避免使用Await.result。
但是,我们什么时候使用它(Await.result)?
下面是使用Await.result的典型用例之一。
假设您已经编写了一个包含主线程的程序,并且主线程中的所有计算都是异步的。现在,在主线程中启动异步计算之后。有些人必须停止主线程的存在,直到异步计算完成,如果程序不停止运行,您将看不到异步计算的结果。
当应用程序开始运行时,有一个非守护进程线程,其任务是执行main()。除非完成非守护进程线程,否则JVM不会自行退出。
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,使用map和flatMap进行简单的Future组合就足够了。
使用(一般为所有阻塞代码)的风险
基于事件的模型中线程的耗尽
在基于事件的模型中,如果阻塞代码需要很长时间才能返回,那么线程就会很快用完。在游戏框架中,任何阻塞调用都会降低应用程序的性能,并且当应用程序耗尽线程时会变得非常慢。
在非事件模型中内存不足
在每个请求模型的线程中。当您有阻塞呼叫时,需要很长时间才能退出/返回。
案例1:如果您有固定的线程池,那么应用程序可能会耗尽线程。
案例2:如果您有动态增长的线程池,那么您的应用程序将遭受太多的上下文切换开销,并且由于内存中阻塞的线程太多,也会耗尽内存。
在所有情况下,对于等待某个IO或其他事件,都没有做任何有用的工作。
https://stackoverflow.com/questions/40795109
复制相似问题