2016-06-11 37 views
3

如果有方法可以限制Scala中未處理期貨的數量,我無法支付資金。 例如在下面的代碼:如何限制Scala中未處理期貨的數量?

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

如果N太大,它最終會拋出OOM。 有沒有辦法限制未處理的期貨以數量隊列式的等待或異常?

+2

這是一般情況,並不僅限於與期貨合作。如果你正在創建/保留大量的任何類型的對象,那麼你最終會耗盡內存。這是你的責任,適當限制這一點。 – JimN

回答

5

因此,最簡單的答案是,您可以創建一個ExecutionContext,用於阻止或限制新任務的執行超出特定限制。見this blog post。有關阻塞Java ExecutorService的更豐富的示例,請參閱an example。 [您可以直接使用它,Maven Central上的庫是here。]這封裝了一些非阻塞ExecutorService,您可以使用java.util.concurrent.Executors的工廠方法創建它。

要將Java ExecutorService轉換爲Scala ExecutionContext只是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。我define loan-pattern methods in Scala [maven central]這兩個創建上下文,並在我完成後關閉它。該代碼最終看起來像...

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 
} 

而不是使用一個ExecutorService,阻止顧左右而言他,你可以使用強制任務調度(Future -creating)Thread執行會減慢速度實例任務而不是異步運行它。您將使用ThreadPoolExecutor.CallerRunsPolicy來製作java.util.concurrent.ThreadPoolExecutor。但是ThreadPoolExecutor直接構建起來相當複雜。

一個較新的,更性感,更斯卡拉爲中心的替代所有的這將是簽出Akka Streams作爲替代Future用於與「背壓」,以防止OutOfMemoryErrors併發執行。

+0

這很有幫助。非常感謝鏈接到maven和whatnot的上下文! – EdgeCaseBerg