2012-02-21 32 views
3

如果超過3秒,我想超時執行一個函數。如何檢查函數執行是否超過指定的秒數?

long startTime = System.currentTimeMillis(); 
getStaticJsonResponse("build", "post"); 
long finishTime = System.currentTimeMillis(); 
long elapsedTime = finishTime - startTime/1000; 
System.out.println("time" + elapsedTime); 
+1

你將不得不使用多線程 – 2012-02-21 09:19:54

回答

-1

只要改變

long elapsedTime = finishTime - startTime/1000; 

long elapsedTime = (finishTime - startTime)/1000; 

,這應該工作。

1

創建一個Timeout類。使用代表所需秒數的參數構建它。給它一個HasTimedOut成員函數。定期在函數中調用該成員,如果返回true,則從該函數返回。

+0

你可以建議一些鏈接,我可以找到這個,因爲我不知道做多線程 – user1195292 2012-02-21 09:24:18

+0

你很可能不需要多線程來做你想做的。 – 2012-02-21 09:25:02

+0

你能否介紹暫停課 – user1195292 2012-02-21 09:35:11

3

我不知道我是否正確解釋問題(因爲其他答案表明否則),但我收集,你想實現您的getStaticJsonResponse()調用超時(我假設是一個阻止網絡通話)?

如果確實如此,這不是一件簡單的事情 - 在同步API上實現超時並不容易。

一種方法是使用任務線程。在這種情況下,您將創建一個新的類像下面這樣:

class JSONRequester implements Runnable 
{ 
    @Override 
    public void run () 
    { 
     getStaticJsonResponse("build", "post"); 
    } 
} 

這基本上只是聲明,可以在一個單獨的線程運行getStaticJsonResponse()類。原始線程隨後可以自由監視任務線程,並在運行時間過長時終止它。

要實現超時(的,也就是說,3秒),然後你可以做類似如下:

... 

// Create and start the task thread. 
Thread taskThread = new Thread(new JSONRequester ()); 
taskThread.start(); 

// Wait 3 seconds. 
sleep(3000); 

// If after waiting 3 seconds the task is still running, stop it. 
if (taskThread.isAlive()) 
    taskThread.interrupt(); 

... 

這裏,主線程啓動任務線程,這反過來又調用您的getStaticJsonResponse()方法。然後等待三秒鐘,並檢查線程是否仍在運行。如果線程正在運行(即getStaticJsonResponse()尚未完成),它將調用線程的interrupt()方法,這將導致InterruptedExceptionJSONRequester s run()方法中拋出,從而終止任務線程。

編輯:我要指出,這是假定對代碼做一點內getStaticJsonResponse(),特別是,無論哪裏的線程被阻塞滿足的條件之一爲響應interrupt()通話上市here。然而,在網絡代碼中(這似乎是),這通常是一個非常安全的假設。

+0

感謝您的信息,我正在努力實現這一點,我會在這裏更新一次,這似乎更清晰 – user1195292 2012-02-21 13:28:13

0

如果您想要處理長時間運行的任務可能需要超過3秒的情況,並且需要在它停止時停止,則應該在單獨的線程中執行長時間運行的任務。最簡單的方法是使用Java的Executor框架。

下面是一個在線程中運行一個可能很長(無限長)的運行任務的基本示例,然後在運行時間超過三秒時將其計時。

public static void main(String[] args) { 
    System.err.println("Start"); 

    ExecutorService executor = Executors.newSingleThreadExecutor(); 
    executor.execute(longRunningTask); 
    try { 
     executor.awaitTermination(3, TimeUnit.SECONDS); 
    } catch (InterruptedException e) { 
     e.printStackTrace(); 
    } 
    System.err.println("Time up - finished? " + executor.isTerminated()); //false 
    executor.shutdownNow(); //runnable thread will be interrupted 
} 

private static Runnable longRunningTask = new Runnable() { 
    @Override 
    public void run() { 
     while (true) { 
      // ... do some long running task 

      //periodically check whether task should be aborted 
      if (Thread.currentThread().isInterrupted()) { //triggered by executor.shutdownNow() above 
       break; //stop long running task 
      } 
     } 
    } 
}; 

請注意,這不會是準確地等於3秒(但足夠接近一個基本的超時),並在真實的場景爲中斷檢查真的應該檢查是否一些(線程安全的,即揮發性)變量也被設置,因爲中斷可能是從另一個線程觸發的(但這超出了本答案的範圍)。

9

您需要有一個單獨的線程,等待方法終止或超時。幸運的是,偉大的Guava庫的創建者已經實現了這一點:只需使用TimeLimiter(在你的情況下,SimpleTimeLimiter)。

您的代碼應該是這樣的:

TimeLimiter limiter = new SimpleTimeLimiter(); 
String result = limiter.callWithTimeout(new Callable<String>() { 
    public String call() { 
     return getStaticJsonResponse("build", "post"); 
    } 
    }, 3, TimeUnit.SECONDS, false); 

(假設你的方法返回一個字符串,否則調整的返回類型)。

請注意,與其他解決方案一樣,這可確保主叫方最多等待3個等待時間。但它不能保證方法執行在3秒後實際中止。如果被調用的代碼如Thread.interrupt()那樣對線程中斷作出反應,它只會被中止。所有等待I/O的函數都這樣做,但你自己的代碼可能不會。

相關問題