Scala 2.10中的新未来对每个操作都使用执行上下文,其中一个动作被异步调用(包括映射,过滤器等).这是否意味着每个动作总是通过执行上下文单独调用,或者在使用相同的执行上下文链接多个转换/过滤器??时,可以优化此步骤?
即如果做f.map(…).filter(…).map(…),全部具有相同的执行上下文,这将调用execute()一次(因为它很聪明,可以组成一个同步函数以上)还是三次?
如果scala的未来没有做上述优化,是否有一个更适合长链组合的替代框架呢?
我无法提供文件的任何链接,这将清楚地说明将会发生什么,但是我们可以进行一个简单的实验来回答你的问题.
只需打开Scala REPL并粘贴以下代码:
import java.util.concurrent.Executors
import scala.concurrent._
implicit val ec = new ExecutionContext {
val threadPool = Executors.newFixedThreadPool(1000);
def execute(runnable: Runnable) {
threadPool.submit(runnable)
println("execute!")
}
def reportFailure(t: Throwable) {}
}
future { 1 } map(_ + 1) filter (_ > 0) map (_ + 2)
它将打印:
阶>未来{1}地图(_ 1)过滤器(_> 0)地图(_ 2)
执行!
执行!
执行!
执行!
res0:scala.concurrent.Future [Int] = scala.concurrent.impl.Promise$DefaultPromise@7ef3de76
所以执行是为您正在做的每一个操作(并且您可以检查文档中每个函数,如map或过滤器)将ExecutionContext作为隐式参数:http://www.scala-lang.org/api/2.10.6/#scala.concurrent.Future)
如果您正在寻找替代框架,您应该检查scalaz Futures.我没有经验与他们,但他们似乎是你正在寻找.检查这个线程:https://groups.google.com/forum/#!msg/scalaz/-PuakIf-g_4/7ydrU5VIfDQJ
Unlike the Future
implementation in scala 2.10,map
and flatMap
do NOT spawn new tasks and do not require an implicit ExecutionContext
. Instead,map
and flatMap
merely add to the current (trampolined) continuation that will be run by the ‘current’ thread,unless explicitly forked via Future.fork
or Future.apply
. This means that Future
achieves much better thread reuse than the 2.10 implementation and avoids needless thread pool submit cycles.
Future
also differs from the scala 2.10 Future
type in that it does not necessarily represent a running computation. Instead,we reintroduce nondeterminism explicitly using the functions of the scalaz.Nondeterminsm
interface. This simplifies our implementation and makes code easier to reason about,since the order of effects and the points of nondeterminism are made fully explicit and do not depend on Scala’s evaluation order.
IMPORTANT NOTE: Future
does not include any error handling and should generally only be used as a building block by library writers who want to build on Future
‘s capabilities but wish to design their own error handling strategy. See scalaz.concurrent.Task
for a type that extends Future
with proper error handling — it is merely a wrapper for Future[Either[Throwable,A]]
with a number of additional convenience functions.