如果有办法限制Scala中未处理的期货数量,我无法资助。 例如,在以下代码中:
import ExecutionContext.Implicits.global
for (i <- 1 to N) {
val f = Future {
//Some Work with bunch of object creation
}
}
如果N太大,它最终会抛出OOM。 有没有办法用类似队列的等待或异常来限制未处理的Futures ether的数量?
答案 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;
。