Multithreading Scala Future和Thread.sleep的怪异行为
我目前正在编写代码来扩展未来的同伴对象。我想实现的一个功能是Multithreading Scala Future和Thread.sleep的怪异行为,multithreading,scala,concurrency,sleep,future,Multithreading,Scala,Concurrency,Sleep,Future,我目前正在编写代码来扩展未来的同伴对象。我想实现的一个功能是Any //returns the future that computes the first value computed from the list. If the first one fails, fail. def any[T](fs: List[Future[T]]): Future[T] = { val p = Promise[T]() fs foreach { f => { f onComple
Any
//returns the future that computes the first value computed from the list. If the first one fails, fail.
def any[T](fs: List[Future[T]]): Future[T] = {
val p = Promise[T]()
fs foreach { f => {
f onComplete {
case Success(v) => p trySuccess v
case Failure(e) => p tryFailure e
}
} }
p.future
}
我试着用计算机测试我的代码
test("A list of Futures return only the first computed value") {
val nums = (0 until 10).toList
val futures =
nums map { n => Future { Thread.sleep(n*1000); n } }
val v = Await.result(Future.any(futures), Duration.Inf)
assert(v === 0)
}
但是返回的值是1,而不是0。当我将睡眠时间切换到n*1000
到(n+1)*1000
时,它工作正常(返回0)
在0上调用sleep时是否有任何特殊效果?
线程。sleep
是将来的阻塞操作
,但您没有向ExecutionContext
发出这样做的信号,因此行为将根据您使用的ExecutionContext和您的计算机拥有的处理器数量而有所不同。如果您添加阻塞
,则您的代码与预期一样工作:
nums map { n => Future { blocking { Thread.sleep(n*1000); n } } }
我认为函数名是
any
,因此我认为您以正确的方式实现any
。
但是如果你想要第一个元素,你只需要从列表参数
fs
中得到第一个元素,并用一个承诺来完成。哦,我忘了添加阻塞
阻塞。我没有注意到这些线程是在执行上下文中运行的。你的解决方案非常有效。谢谢。我想我在评论中误用了“第一”这个词。我想——以及需求描述的——返回首先在时域中计算的值。我非常确定这个实现满足了需求。