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

时间:2015-10-29 00:48:44

标签: scala future execution systemtime

当然,人们可以在未来的第一线收集系统时间。但是:

是否可以在无法访问未来代码的情况下知道该时间。 (在我的情况下,返回未来的方法将由'框架的用户提供。)

def f: Future[Int] = ...

def magicTimePeak: Long = ???

1 个答案:

答案 0 :(得分:2)

Future本身并不是真的知道这一点(也不是为了照顾它)。当代码实际执行时,这完全取决于执行程序。这取决于线程是否立即可用,如果没有,何时可用。

我想你可以包裹Future来跟踪它。它将涉及创建一个带有闭包的基础Future,该闭包可以更改包装类中的可变var。由于您只需要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的创建,那么您无法确定何时开始。