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

在Scala中花费太多时间时,如何终止函数?,scala,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 = Sy

最近,我正在学习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
  }
}

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

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

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


注意:由于您是Scala初学者:线程通常不是Scala的发展方向,但在本例中,Scala提供的抽象(即未来)对于您想要实现的目标来说还不够低。请不要把低级线程的方式看作是你每天都应该做的事情。

< P>现在的计算阻塞了你的主线程。这就是程序运行的线程。在计算完成之前,您无法控制在该线程上执行任何操作

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

注意:由于您是Scala初学者:线程通常不是Scala的发展方向,但在本例中,Scala提供的抽象(即未来)对于您想要实现的目标来说还不够低。请不要把低级线程作为你每天应该做的事情。

< P>使用期货!
val resultFuture : Future[ReturnType] = Future.apply {
 longComputation
}

val resultMaybeCut = Await.result(resultFuture, DurationOfChoice)
对于记录,Await.resultawaitable:Awaitable[T],atMost:Duration:

如果当前线程在等待时被中断,则引发InterruptedException 如果在等待指定的时间后,可等待的对象仍未就绪,则引发TimeoutException 如果atMost为Duration,则引发IllegalArgumentException。未定义 警告谢谢@Markusthoemes:

这样做不会中断潜在的未来计算,只会让您轻松地超时!这可能是个问题,也可能不是。 如果我相信没有超简单的方法可以真正停止底层计算,那么您可能需要参考这里发布的其他解决方案

使用未来

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

val resultMaybeCut = Await.result(resultFuture, DurationOfChoice)
对于记录,Await.resultawaitable:Awaitable[T],atMost:Duration:

如果当前线程在等待时被中断,则引发InterruptedException 如果在等待指定的时间后,可等待的对象仍未就绪,则引发TimeoutException 如果atMost为Duration,则引发IllegalArgumentException。未定义 警告谢谢@Markusthoemes:

这样做不会中断潜在的未来计算,只会让您轻松地超时!这可能是个问题,也可能不是。
如果我相信没有超简单的方法可以真正停止底层计算,那么您可能需要参考这里发布的其他解决方案

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

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
}

如果存在紧密循环,并且在特定超时之前未满足条件时只想退出,则不严格要求线程:

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
}

你能给我一个小的演示,因为我不知道线程。谢谢我在工作中使用Maple和MATLAB已经有5年了。你可以参考。对于线程的简短介绍。@markusthoemes为什么未来不是这里的发展方向?如果时间是在未来块中计算的,那么未来的管理至少不会对时间度量产生任何影响,这就是我的理解。你能给我一个小的演示吗,因为我不知道线程。谢谢我在工作中使用Maple和MATLAB已经有5年了。你可以参考。对于线程的简短介绍。@markusthoemes为什么未来不是这里的发展方向?如果时间是在未来块中计算的,那么未来的管理至少不会对时间度量产生任何影响,这就是我的理解。谢谢。我展示的代码只是我制作的一个简单示例。事实上,我想找到一种方法来处理一般用户定义的函数,它是由他人编写的,或者我不能改变它。公平地说,我认为重要的是,您不需要跳转到线程来约束执行时间。对于Mathematica用户,一般来说,我使用ALT+。中止Mathematica内核的计算:很好!比跳转到线程更简单的解决方案,你是对的。谢谢。我展示的代码只是我制作的一个简单示例。事实上,我想找到一种方法来处理一般用户定义的函数,它是由他人编写的,或者我不能改变它。公平地说,我认为重要的是,您不需要跳转到线程来约束执行时间。对于Mathematica用户,一般来说,我使用ALT+。中止Mathematica内核的计算:很好!比跳转到线程更简单的解决方案是
是的,我不认为这会停止计算。在这种情况下,它会退出程序,但将来通常不会停止计算。这是一个非常好的观点,取决于用例!我正在寻找有关它的相关文档,如果你有任何链接,请不要犹豫与我联系:我不认为这实际上停止了计算。在这种情况下,它会退出程序,但将来通常不会停止计算。这是一个非常好的观点,取决于用例!我正在寻找相关文档,如果您有任何以下信息,请随时与我联系: