我正试图理解Scala中的future,而我来自Java背景:我了解到你可以这样写:
val f = Future { ... }
那我有两个问题:
- 这个定时器是如何被调度的?是自动的吗?
- 它将使用哪个调度程序?在Java中,您可以使用可作为线程池等的执行程序。
此外,我如何实现一个 scheduledFuture
,即在特定时间延迟后执行的任务?谢谢
我正试图理解Scala中的future,而我来自Java背景:我了解到你可以这样写:
val f = Future { ... }
那我有两个问题:
此外,我如何实现一个 scheduledFuture
,即在特定时间延迟后执行的任务?谢谢
Future { ... }
块是对调用 Future.apply
的语法糖(正如您所知,Maciej),并将代码块作为第一个参数传递。ExecutionContext
- 这个上下文决定了它将如何执行。 因此,回答您的第二个问题,将由处于隐式范围内的任何 ExecutionContext 执行 future(当然,如果这是模棱两可的,则是编译时错误)。import ExecutionContext.Implicits.global
导入的上下文,默认情况下使用带有每个处理器核心一个线程的 ThreadPoolExecutor
,但可以通过系统属性进行调整。ExecutionContext
,始终在执行之前应用相同的延迟。 但是,如果您想要从调用站点控制延迟,那么您当然不能使用 Future.apply
,因为没有参数来传达应该如何安排此操作。 在这种情况下,我建议直接将任务提交给计划的执行程序。import scala.concurrent.ExecutionContext.Implicits._
) 实际上就是一个 java.util.concurrent.Executor
,整个ExecutionContext概念只是一个非常薄的封装,但与Java的executor框架密切相关。val p = Promise[Int]()
来创建一个promise(假设范围内有 ExecutionContext
)。我们承诺一个整数。p.future
来抓取它,这只是一个Scala未来。p.successful(3)
,此时未来将完成。object Promise {
private val timer = new java.util.Timer()
def timeout[A](message: => A, duration: Long, unit: TimeUnit = TimeUnit.MILLISECONDS)
(implicit ec: ExecutionContext): Future[A] = {
val p = Promise[A]()
timer.schedule(new java.util.TimerTask {
def run() {
p.completeWith(Future(message)(ec))
}
}, unit.toMillis(duration))
p.future
}
}
val future3 = Promise.timeout(3, 10000) // will complete after 10 seconds
Thread.sleep(10000)
要好得多,后者会阻塞线程并强制进行上下文切换。val p = Promise...
和结尾的p.future
。这是使用Promise时的常见模式。这意味着该函数向客户端做出某些承诺,并启动异步计算以实现它。concurrent
包对象的小写future
方法,而不是Future.apply
。前者简单地委托给后者。个人而言,我更喜欢小写的future
。
Future
(即一种只能写入一次值的容器,执行器必须在某个时刻插入值)。调用者/客户端没有直接使用Promise
来控制调度的方法。 - Andrzej Doyle