因此,最簡單的答案是,您可以創建一個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
併發執行。
這是一般情況,並不僅限於與期貨合作。如果你正在創建/保留大量的任何類型的對象,那麼你最終會耗盡內存。這是你的責任,適當限制這一點。 – JimN