假设我有一个函数,它调用一个阻塞可中断操作。我想在超时的情况下异步运行它。也就是说,我想在超时到期时中断函数。
所以我正在尝试做这样的事情:
import scala.util.Try import scala.concurrent.Future def launch(f: () => Unit, timeout: Int): Future[Try[Unit]] = { val aref = new java.util.concurrent.atomic.AtomicReference[Thread]() import ExecutionContext.Implicits.global Future {Thread.sleep(timeout); aref.get().interrupt} // 1 Future {aref.set(Thread.currentThread); Try(f())} // 2 }
问题是 (1) 中的 aref
可以为 null,因为 (2) 尚未将其设置为当前线程。在这种情况下,我想等到 aref
设置完毕。最好的方法是什么?
如果添加一个< code>CountDownLatch,就可以实现您想要的行为。(请注意,在很多很多的< code>Future中发生阻塞(即,在< code>await处停滞)可能会导致线程池的饥饿。)
import scala.util.Try
import scala.concurrent.Future
def launch(f: () => Unit, timeout: Int): Future[Try[Unit]] = {
val aref = new java.util.concurrent.atomic.AtomicReference[Thread]()
val cdl = new java.util.concurrent.CountDownLatch(1)
import ExecutionContext.Implicits.global
Future {Thread.sleep(timeout); cdl.await(); aref.get().interrupt} // 1
Future {aref.set(Thread.currentThread); cdl.countDown(); Try(f())} // 2
}
我也需要相同的行为,所以这就是我解决它的方式。我基本上创建了一个对象,该对象创建一个计时器,如果将来未在指定的持续时间内完成,则使用TimeoutException使promise失败。
package mypackage
import scala.concurrent.{Promise, Future}
import scala.concurrent.duration.FiniteDuration
import akka.actor.ActorSystem
import scala.concurrent.ExecutionContext.Implicits.global
object TimeoutFuture {
val actorSystem = ActorSystem("myActorSystem")
def apply[A](timeout: FiniteDuration)(block: => A): Future[A] = {
val promise = Promise[A]()
actorSystem.scheduler.scheduleOnce(timeout) {
promise tryFailure new java.util.concurrent.TimeoutException
}
Future {
try {
promise success block
}
catch {
case e:Throwable => promise failure e
}
}
promise.future
}
}
您可以使用Await实现稍微简单一点的方法。< code>Await.result方法将超时持续时间作为第二个参数,并在超时时引发< code>TimeoutException。
try {
import scala.concurrent.duration._
Await.result(aref, 10 seconds);
} catch {
case e: TimeoutException => // whatever you want to do.
}
有一个方面的未来,我不完全理解从官方教程参考。http://docs.scala-lang.org/overviews/core/futures.html scala中的期货是否有某种内置的超时机制?假设下面的示例是一个5GB的文本文件...“Implicits.global”的隐含范围最终会导致onFailure以非阻塞方式触发还是可以定义?如果没有某种默认的超时,这是否意味着成功或失败都不会触
我无法使用截击库。我不想无限期地等待请求,所以我不想设置超时。但它不起作用。我在其他地方也有同样的东西(我使用RequestFuture而不是RequestFuture),它运行良好,但在这里我无法将其设置为工作状态。 如果你能提供任何帮助,那就太棒了!谢谢
是否有可能“反转”Scala的未来? 有时候,未来成功的结果意味着错误。在这种情况下,翻转一个未来会很好,即调用一个返回未来的函数,如果最初的未来失败,则该函数以指定的值成功,如果最初的未来成功,则以指定的错误失败。
我有一个scala.html页面,它在Play 2.2.1、Scala 2.10.2、Slick 1.0.1、Postgres 9.3应用程序中调用AJAX。 以下同步代码工作正常。它解析请求查询字符串并调用方法 ,该方法对表进行 scala 光滑调用,并根据 对象过滤结果并返回 如果我将方法改为异步运行(见下文),并多次调用listSchools,那么大约20秒后就会抛出这个异常。我怀疑这可能是
Scala中有没有不会失败的< code >未来这个概念? 我正在将可能失败,因此我同时处理和--到,并带有从失败或成功状态派生的可选错误消息。目前为止,一切都好。 现在的情况是,我想正式地(即在类型系统的帮助下)记住,这个未来将始终保持,并且我将来不需要处理失败案例。 有什么聪明的方法可以做到这一点吗?
我正在阅读Scala Cookbook(http://shop.oreilly.com/product/0636920026914.do) 有一个与未来使用相关的例子,涉及理解。 到目前为止,我对理解的理解是,当与一个集合一起使用时,它会产生另一个相同类型的集合。例如,如果每个< code>futureX的类型为< code>Future[Int],则以下内容也应为< code>Future[In