如何限制未来的执行?

时间:2018-01-06 07:33:34

标签: scala future throttling

我基本上有唯一ID的列表,并且对于每个id,我调用函数返回未来。 问题是单个电话中的期货数量是可变的。

list.map(id - > futureCall) 会有太多的并行性会影响我的系统。我想并行配置期货执行数量。 我想要可测试的设计,所以我不能做this 经过很多搜索,我找到了this 我没有得到它如何使用它。我试过了,但没用。

之后,我刚刚将我的课程导入我的班级,我正在打电话。 我使用了相同的片段并将默认的maxConcurrent设置为4。 我用ThrottledExecutionContext

替换了导入全局执行上下文

2 个答案:

答案 0 :(得分:2)

您必须使用ExecutionContext包裹ThrottledExecutionContext

这是一个小样本:

object TestApp extends App {

  implicit val ec = ThrottledExecutionContext(maxConcurrents = 10)(scala.concurrent.ExecutionContext.global)

  def futureCall(id:Int) = Future {
    println(s"executing $id")
    Thread.sleep(500)
    id
  }

  val list = 1 to 1000
  val results = list.map(futureCall)

  Await.result(Future.sequence(results), 100.seconds)
}

或者您也可以尝试FixedThreadPool

implicit val ec = ExecutionContext.fromExecutor(java.util.concurrent.Executors.newFixedThreadPool(10))

答案 1 :(得分:1)

我不确定你在这里要做什么。默认global ExecutionContext使用与CPU内核一样多的线程。那么,这将是你的并行性。如果那仍然太多"对于您,您可以使用系统属性控制该数字:"scala.concurrent.context.maxThreads",并将其设置为较低的数字。

这将是在任何给定时间并行执行的最大期货数量。你不应该明确地限制任何东西。

或者,您可以创建自己的执行程序,并为其提供容量有限的BlockingQueue。这会阻碍生产者方面(当提交工作项时),就像你的实现一样,但我非常强烈建议你这样做,因为它非常危险并且容易出现死锁,而且效率也低得多,默认ForkJoinPool实施。