尽管您已经得到了一些关于如何通过阻塞附加线程来处理超时来实现它的答案,但我建议您尝试一种不同的方式,原因是 Rex Kerr 已经给出了。我不完全知道你在做什么f()
,但如果它是 I/O 绑定的,我建议你只使用异步 I/O 库。如果它是某种循环,您可以将超时值直接传递给该函数并在TimeoutException
那里抛出一个,如果它超过超时。例子:
import scala.concurrent.duration._
import java.util.concurrent.TimeoutException
def doSth(timeout: Deadline) = {
for {
i <- 0 to 10
} yield {
Thread.sleep(1000)
if (timeout.isOverdue)
throw new TimeoutException("Operation timed out.")
i
}
}
scala> future { doSth(12.seconds.fromNow) }
res3: scala.concurrent.Future[scala.collection.immutable.IndexedSeq[Int]] =
scala.concurrent.impl.Promise$DefaultPromise@3d104456
scala> Await.result(res3, Duration.Inf)
res6: scala.collection.immutable.IndexedSeq[Int] =
Vector(0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10)
scala> future { doSth(2.seconds.fromNow) }
res7: scala.concurrent.Future[scala.collection.immutable.IndexedSeq[Int]] =
scala.concurrent.impl.Promise$DefaultPromise@f7dd680
scala> Await.result(res7, Duration.Inf)
java.util.concurrent.TimeoutException: Operation timed out.
at $anonfun$doSth$1.apply$mcII$sp(<console>:17)
at $anonfun$doSth$1.apply(<console>:13)
at $anonfun$doSth$1.apply(<console>:13)
at scala.collection.TraversableLike$$anonfun$map$1.apply(TraversableLike.scala:244)
...
scala> res7.value
res10: Option[scala.util.Try[scala.collection.immutable.IndexedSeq[Int]]] =
Some(Failure(java.util.concurrent.TimeoutException: Operation timed out.))
这将仅使用 1 个线程,该线程将在超时 + 单个步骤的执行时间后终止。