简体   繁体   English

是否因为嵌套期货而产生开销

[英]Is there an overhead because of nesting Futures

I wrote this code 我写了这段代码

package com.abhi
import scala.concurrent._
import scala.concurrent.ExecutionContext.Implicits.global

object FutureNesting extends App {

   def measure(future: => Future[Unit]) : Future[Long] = {
      val start = System.currentTimeMillis()
      val ec = implicitly[ExecutionContext]
      val t = future
      t map { case _ =>
         val end = System.currentTimeMillis()
         end - start
      }
   }

   measure(Future{ Thread.sleep(10000) }) onSuccess {case a => println(a)}
   scala.io.StdIn.readLine()
}

So how many threads am I using in this code. 所以我在这段代码中使用了多少个线程。 The broader question is that what is the impact of going on nesting future inside futures. 更广泛的问题是,将期货嵌套在期货内部会产生什么影响。

So I ran the application above and observed it using Visual VM. 因此,我在上面运行了该应用程序,并使用Visual VM对其进行了观察。 This is what I saw 这就是我所看到的

在此处输入图片说明

So the application launched 2 threads ForkJoinPool-1-worker-5 and ForkJoinPool-2-worker-3. 因此,该应用程序启动了2个线程ForkJoinPool-1-worker-5和ForkJoinPool-2-worker-3。 However it launches the same 2 threads even if I remove the nesting. 但是,即使我删除了嵌套,它也会启动相同的2个线程。 So I am not sure what is the overhead because of nesting the futures like above. 因此,由于像上述那样嵌套期货,所以我不确定会有什么开销。

Edit:: Some people said it depends on the type of ThreadPool (ForkJoin etc). 编辑::有人说这取决于ThreadPool的类型(ForkJoin等)。

I won't know what type of pool do Akka.HTTP or Spray use? 我不知道Akka.HTTP或Spray使用哪种类型的池? I planned to use a code snippet similar to the one above in a Spray web service. 我计划在Spray Web服务中使用与上述代码段相似的代码段。 The idea was to measure the performance of the web service using Futures. 这个想法是使用Futures来衡量Web服务的性能。

In your case, you are using wrap over thradpool (ForkJoingPool from java.util.concurrent). 在您的情况下,您正在使用thradpool的包装(java.util.concurrent中的ForkJoingPool)。 Of course, all Futures are executed in it. 当然,所有期货都在其中执行。

 import scala.concurrent.ExecutionConext.Implicits.global

Based on this you must implicitly instantiate pool instead import, like this: 基于此,您必须隐式实例化池而不是导入,如下所示:

implicit val ec: ExecutionContext

And use method from ForkJoinPool: getActiveThreadCount() 并使用ForkJoinPool中的方法: getActiveThreadCount()

Second approach: You can open profiler (like JProfiler - from Jetbrains or Jvisualvm - attached with jdk) and watch meta information including threads parameters like their amount, activity, memory usage and etc. 第二种方法:您可以打开事件探查器(例如来自Jetbrains的JProfiler或Jvisual附带的Jvisualvm)并查看元数据信息,包括线程参数,例如线程的数量,活动,内存使用情况等。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM