2017-06-06 209 views
0

最近,我正在學習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

上面階代碼需要大約70。

回答

2

現在的計算會阻止您的主線程。那就是你的程序運行的線程。在你的計算完成之前,你沒有控制權去執行那個線程上的任何東西。

您可以在單獨運行Thread的計算中運行該計算,並在您認爲計算時間過長時從主線程中刪除Thread

注:當你是一個初學者斯卡拉:線程通常不是在斯卡拉的路要走,但在這種情況下,由斯卡拉(即Future S)提供的抽象不適合你低電平足夠的」重新努力實現。請不要把低層次的Thread作爲你每天應該做的事情。

+0

你能不能給我一個小的演示,因爲我不不知道'Thread'。謝謝。我在工作中使用Maple和MATLAB大約5年。 – xyz

+0

您可以參考https://twitter.github.io/scala_school/concurrency.html#Thread。有關線程的簡短介紹。 – markusthoemmes

+0

@markusthoemmes爲什麼不是'未來'的方式去這裏?如果在「未來」區塊中計算時間,則「未來」管理應該不會對時間測量產生任何影響(至少,這是我的理解)。 –

4

使用未來(S)!

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

val resultMaybeCut = Await.result(resultFuture, DurationOfChoice) 

對於記錄,Await.result(awaitable:Awaitable [T],atMost:持續時間):

  • 拋出InterruptedException的如果在等待時
  • 當前線程被中斷拋出TimeoutException異常如果後等待指定的時間awaitable仍未準備好
  • 如果atMost是Duration.Undefined,則拋出IllegalArgumentException異常

警告(謝謝@markusthoemmes):

這樣做並不會打斷未來的計算,它只是讓您輕鬆超時! (這可能是也可能不是問題)。 如果我相信Kill or timeout a Future in Scala 2.10有沒有超簡單的方法來實際停止底層計算,所以你可能想參考其他解決方案張貼在這裏!

+0

我不認爲這實際上會停止計算。它退出程序(在這種情況下),但通常不會在將來停止計算。 – markusthoemmes

+0

這是一個很好的觀點,取決於用例!我正在尋找相關的文件,請不要猶豫,如果你有任何聯繫:) – C4stor

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 
} 
+0

謝謝。我展示的代碼只是我做的一個簡單的例子。實際上,我想找到一種方法來處理由其他人編寫的一般用戶定義函數,否則我不能**改變它。 – xyz

+0

不夠公平,我認爲考慮你不需要跳轉到線程來約束執行時間是非常重要的。 – SimonC

+0

對於*** Mathematica ***用戶,通常我使用Alt +。 '放棄*** Mathematica ***核心的計算:) – xyz

相關問題