如何在Scala中花费太多时间来终止函数?

时间:2017-06-06 13:08:14

标签: scala

最近,我正在学习Scala语言。今天我提出一个问题,就是说, 如何在需要太多时间时终止函数。

例如:

object HelloWorld {
  def main(args: Array[String]) {
    println("Hello, World")
    // How to terminate the sum() function
    // when the time that it takes greater than 2 second?
    val t0 = System.nanoTime : Double
    val total: BigInt = sum(1000000000)
    val t1 = System.nanoTime : Double
    println("Elapsed time " + (t1 - t0) / 1000000.0 + " msecs")

    println(total)

  }

  //Given that sum() is written by others and I cannot change it.
  def sum(k: Int): BigInt = {
    var total: BigInt = 0
    for (i <- 1 to k) {
      total += i
    }
    total
  }
}

enter image description here

上面的scala代码大约需要70秒。

3 个答案:

答案 0 :(得分:4)

使用未来!

val resultFuture : Future[ReturnType] = Future.apply {
 longComputation
}

val resultMaybeCut = Await.result(resultFuture, DurationOfChoice)

记录中,Await.result(等待:Awaitable [T],atMost:Duration):

    如果当前线程在等待时被中断,则
  • 抛出InterruptedException
  • 如果在等待指定时间awaitable之后仍未准备好,则抛出TimeoutException
  • 如果atMost是Duration.Undefined ,则
  • 抛出IllegalArgumentException

警告(感谢@markusthoemmes):

这样做不会中断潜在的未来计算,只是让你轻松超时! (这可能是也可能不是问题)。 如果我相信Kill or timeout a Future in Scala 2.10没有超级简单的方法来实际停止基础计算,那么你可能想要参考这里发布的其他解决方案!

答案 1 :(得分:2)

现在的计算会阻止你的主线程。这是你的程序运行的线程。在计算完成之前,你无法控制在该线程上执行任何操作。

您可以在单独的Thread中运行计算,并在您认为花费太长时间后从主线程中删除Thread

注意:因为你是Scala的初学者:线程通常不是Scala的方式,但在这种情况下是Scala提供的抽象(即Future s )对于你想要达到的目标而言,其水平不够低。请不要将低级Thread方式视为您每天应该做的事情。

答案 2 :(得分:1)

如果您有一个紧凑的循环并且只是想在某个超时之前不满足条件时退出,则严格要求线程:

def sum(k: Int, timeoutMillis: Long): BigInt = {
  val timeoutMillis = System.currentTimeMillis + timeoutMillis
  var total: BigInt = 0
  for (i <- 1 to k) {
    total += i
    if (timeoutMillis < System.currentTimeMillis) 
      throw new RuntimeException("Timed out")
  }
  total
}