如何限制Scala中未处理的Futures数量?

时间:2016-06-11 00:57:45

标签: scala parallel-processing

如果有办法限制Scala中未处理的期货数量,我无法资助。 例如,在以下代码中:

import ExecutionContext.Implicits.global    
for (i <- 1 to N) {
  val f = Future {
    //Some Work with bunch of object creation
  }
}

如果N太大,它最终会抛出OOM。 有没有办法用类似队列的等待或异常来限制未处理的Futures ether的数量?

1 个答案:

答案 0 :(得分:5)

因此,最简单的答案是您可以创建一个ExecutorService来阻止或限制超出某个限制的新任务的执行。见this blog post。有关阻塞Java ExecutorService的更加充实的示例,这里是an example。 [如果需要,可以直接使用它,Maven Central上的库是here。]这包含了一些非阻塞java.util.concurrent.Executors,您可以使用ExecutorService的工厂方法创建。{/ p>

将Java ExecutionContext转换为Scala ExecutionContext.fromExecutorService( executorService )只是import java.util.concurrent.{ExecutionContext,Executors} import com.mchange.v3.concurrent.BoundedExecutorService val executorService = new BoundedExecutorService( Executors.newFixedThreadPool( 10 ), // a pool of ten Threads 100, // block new tasks when 100 are in process 50 // restart accepting tasks when the number of in-process tasks falls below 50 ) implicit val executionContext = ExecutionContext.fromExecutorService( executorService ) // do stuff that creates lots of futures here... 。因此,使用上面链接的库,您可能会有像......

这样的代码
ExecutorService

如果你想要一个有限的ExecutorService,那将会持续你整个申请的时间。但是,如果您在代码中的本地化点创建了大量未来,那么当您完成它时,您将需要关闭import com.mchange.sc.v2.concurrent.ExecutionContexts ExecutionContexts.withBoundedFixedThreadPool( size = 10, blockBound = 100, restartBeneath = 50 ) { implicit executionContext => // do stuff that creates lots of futures here... // make sure the Futures have completed before the scope ends! // that's important! otherwise, some Futures will never get to run } 。我define loan-pattern methods in Scala [maven central]创建了上下文,并在完成后将其关闭。代码最终看起来像......

ExecutorService

不是使用直接阻止的Future,而是可以通过强制执行任务调度(Thread - 创建)java.util.concurrent.ThreadPoolExecutor来执行任务,从而减慢速度。而不是异步运行它。您使用ThreadPoolExecutor.CallerRunsPolicy制作Future。但ThreadPoolExecutor直接构建起来相当复杂。

更新,更性感,更以Scala为中心的替代方法是将Akka Streams作为OutOfMemoryErrors的替代方案,以便与&#34;背压&#34;防止self.tableView.tableHeaderView = self.searchController.searchBar;