scala.concurrent.Future的执行何时开始?



当然,我们可以在未来身体的第一行收集系统时间。但:

是否有可能在无法访问未来代码的情况下知道那个时间。(在我的例子中,返回未来的方法将由"框架"的用户提供。

def f: Future[Int] = ...
def magicTimePeak: Long = ???

Future本身并不真正知道这一点(也不是为了关心而设计的(。当代码实际执行时,这完全取决于执行器。这取决于线程是否立即可用,如果不是,则当线程可用时可用。


我想你可以包装Future来跟踪它。这将涉及创建一个具有闭包的基础Future,该闭包更改包装类中的可变变量。由于您只需要一个 Long ,如果Future尚未开始执行,则必须默认为零,尽管将其更改为Option[Date]或其他内容是微不足道的。

class WrappedFuture[A](thunk: => A)(implicit ec: ExecutionContext) {
    var started: Long = 0L
    val underlying = Future {
        started = System.nanoTime / 1000000 // milliseconds
        thunk
    }
}

为了证明它有效,请创建一个带有一个线程的固定线程池,然后给它一个阻塞任务,比如 5 秒。然后,创建一个WrappedFuture,并在稍后检查其started值。请注意记录时间的差异。

import java.util.concurrent.Executors
import scala.concurrent._
val executorService = Executors.newFixedThreadPool(1)
implicit val ec = ExecutionContext.fromExecutorService(executorService)
scala> println("Before blocked: " + System.nanoTime / 1000000)
Before blocked: 13131636
scala> val blocker = Future(Thread.sleep(5000))
blocker: scala.concurrent.Future[Unit] = scala.concurrent.impl.Promise$DefaultPromise@7e5d9a50
scala> val f = new WrappedFuture(1)
f: WrappedFuture[Int] = WrappedFuture@4c4748bf
scala> f.started
res13: Long = 13136779 // note the difference in time of about 5000 ms from earlier

但是,如果您不控制Future的创建,则无法确定它何时开始。

最新更新