Scala 未来/成功竞赛
我正在学习期货,我正在尝试创建一个方法,将两个期货作为参数 (Scala 未来/成功竞赛,scala,concurrency,future,Scala,Concurrency,Future,我正在学习期货,我正在尝试创建一个方法,将两个期货作为参数 (f和g)并返回成功完成的第一个未来,否则返回f或g 说明我的方法行为的一些用例有: Future 1 | Future 2 | Result Success First Success Second Future 1 Success First Failure Second Future 1 Success Second Success First Futu
f
和g
)并返回成功完成的第一个未来,否则返回f
或g
说明我的方法行为的一些用例有:
Future 1 | Future 2 | Result
Success First Success Second Future 1
Success First Failure Second Future 1
Success Second Success First Future 2
Success Second Failure First Future 1
Failure First Failure Second Future 2 (because we had a failure on Future 1, so try to see what is the result Future 2)
所以我创建了这个方法:
def successRace(f: Future[T], g: Future[T]): Future[T] = {
val p1 = Promise[T]()
val p2 = Promise[T]()
val p3 = Promise[T]()
p1.completeWith(f)
p2.completeWith(g)
p3. ????
p3.future
}
现在,我怎么知道哪一个先完成 您想使用
trycomplewith
方法。它可以被调用多次,并且只有第一次完成以后的胜利
def successRace(f: Future[T], g: Future[T]): Future[T] = {
val p = Promise[T]()
p.tryCompleteWith(f)
p.tryCompleteWith(g)
p.future
}
我完全同意前面的答案,但我希望我的例子能进一步澄清这一点,因此:
def successRace[T](f: Future[T], g: Future[T]): Future[T] = {
val promise = Promise[T]()
f onComplete(promise.tryComplete(_))
g onComplete(promise.tryComplete(_))
promise.future
}
因此,第一次完成的
未来
将设置包装在Try
中的值(因此,成功
或失败
)。用例是第一次成功完成:
scala> :pa
// Entering paste mode (ctrl-D to finish)
def firstSuccessOf[T](fs: Future[T]*)(implicit x: ExecutionContext): Future[T] = {
val p = Promise[T]()
val count = new java.util.concurrent.atomic.AtomicInteger(fs.size)
def bad() = if (count.decrementAndGet == 0) { p tryComplete new Failure(new RuntimeException("All bad")) }
val completeFirst: Try[T] => Unit = p tryComplete _
fs foreach { _ onComplete { case v @ Success(_) => completeFirst(v) case _ => bad() }}
p.future
}
// Exiting paste mode, now interpreting.
firstSuccessOf: [T](fs: scala.concurrent.Future[T]*)(implicit x: scala.concurrent.ExecutionContext)scala.concurrent.Future[T]
所以
或
@ysusuk的答案是未来。firstCompletedOf在引擎盖下做什么。你能看到这个吗。按照我所描述的,它应该返回未来g,因为未来f失败了,用你的方法,它试图用首先完成的未来来完成承诺,但它不关心它是否失败。答案与我在上面的评论中所说的问题不匹配,您的实现试图完成承诺,但它不关心是失败还是否。请参阅其他注释中的粘贴栏。@user2336315您肯定是对的,此实现不关心第一次完成的
未来(成功或失败)的结果。
scala> def f = Future { Thread sleep 5000L ; println("Failing") ; throw new NullPointerException }
f: scala.concurrent.Future[Nothing]
scala> def g = Future { Thread sleep 10000L ; println("OK") ; 7 }
g: scala.concurrent.Future[Int]
scala> firstSuccessOf(f,g)
res3: scala.concurrent.Future[Int] = scala.concurrent.impl.Promise$DefaultPromise@5ed53f6b
scala> res0Failing
3.value
res4: Option[scala.util.Try[Int]] = None
scala> res3.valueOK
res5: Option[scala.util.Try[Int]] = Some(Success(7))
scala> def h = Future { Thread sleep 7000L ; println("Failing too") ; throw new NullPointerException }
h: scala.concurrent.Future[Nothing]
scala> firstSuccessOf(f,h)
res10: scala.concurrent.Future[Nothing] = scala.concurrent.impl.Promise$DefaultPromise@318d30be
scala>
scala> res10.Failing
value
res11: Option[scala.util.Try[Nothing]] = None
scala> Failing too
scala> res10.value
res12: Option[scala.util.Try[Nothing]] = Some(Failure(java.lang.RuntimeException: All bad))