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
中得到第一个元素,并用一个承诺来完成。

哦,我忘了添加
阻塞
阻塞。我没有注意到这些线程是在执行上下文中运行的。你的解决方案非常有效。谢谢。我想我在评论中误用了“第一”这个词。我想——以及需求描述的——返回首先在时域中计算的值。我非常确定这个实现满足了需求。