2011-03-09 566 views
8

我有一個方法返回一個字符串,是否有可能超過一定的時間treshold fot該方法返回一些特定的字符串?設置在java中的方法的運行時間限制

+0

你想要啥子是打電話給你的方法,如果其執行時間超過一定量的返回字符串是一個常數? – reef 2011-03-09 08:47:39

+0

@reef nop,當返回一些字符串的方法x達到6秒運行時,它返回一些錯誤字符串..或者只是有一些我可以用來處理時間錯誤的回調。 – London 2011-03-09 08:49:50

回答

14

Guava library有一個非常好的TimeLimiter,它可以讓你在接口定義的任何方法上做到這一點。它可以爲具有「內置」超時的對象生成代理。

+0

這似乎是,只是讓我問你這個,這個例子對我來說不是很清楚,因爲我是noob,'要返回target.someMethod()'的值,這個'target'是指類實例嗎? – London 2011-03-09 09:11:53

+0

另一個問題,如果這種方法打開一些會話,它們會關閉嗎?或者我需要在返回默認值之前將此關閉會話? – London 2011-03-09 09:18:29

+0

@倫敦。 1)是的,這就是它的意思。 2)該方法需要使用'try {...} finally {...}'來關閉這些會話。但它應該是這樣做的! – 2011-03-09 09:24:57

9

我在過去用Runtime.getRuntime().exec(command)產生外部進程時做了類似的事情。我想你可以在你的方法中做這樣的事情:

Timer timer = new Timer(true); 
InterruptTimerTask interruptTimerTask = 
    new InterruptTimerTask(Thread.currentThread()); 
timer.schedule(interruptTimerTask, waitTimeout); 
try { 
    // put here the portion of code that may take more than "waitTimeout" 
} catch (InterruptedException e) { 
    log.error("timeout exeeded); 
} finally { 
    timer.cancel(); 
} 

,這裏是InterruptTimerTask

/* 
* A TimerTask that interrupts the specified thread when run. 
*/ 
protected class InterruptTimerTask extends TimerTask { 

    private Thread theTread; 

    public InterruptTimerTask(Thread theTread) { 
     this.theTread = theTread; 
    } 

    @Override 
    public void run() { 
     theTread.interrupt(); 
    } 

} 
+0

「Scedule」不是用作時間限制,而是延遲......所以在這種情況下,「waitTimeout」是在執行interruptTimerTask之前的延遲...從API:在指定之後安排執行指定任務延遲。 – Kayvar 2013-04-26 17:21:44

+2

我在try/catch中遇到一個錯誤:'InterruptedException的Unreachable catch塊。這個異常永遠不會從try語句體中拋出 – Michael 2014-05-13 15:11:10

1

作爲回答的@MarcoS

我發現超時不提高,如果方法是鎖定的東西而不是釋放CPU時間到定時器。 然後Timer不能啓動新的線程。 因此,我立即改變了一下開始線程,睡在線程內。

 InterruptTimerTaskAddDel interruptTimerTask = new InterruptTimerTaskAddDel(
       Thread.currentThread(),timeout_msec); 

     timer.schedule(interruptTimerTask, 0); 

     /* 
* A TimerTask that interrupts the specified thread when run. 
*/ 
class InterruptTimerTaskAddDel extends TimerTask { 

    private Thread theTread; 
    private long timeout; 

    public InterruptTimerTaskAddDel(Thread theTread,long i_timeout) { 
     this.theTread = theTread; 
     timeout=i_timeout; 
    } 

    @Override 
    public void run() { 
     try { 
      Thread.currentThread().sleep(timeout); 
     } catch (InterruptedException e) { 
      // TODO Auto-generated catch block 
      e.printStackTrace(System.err); 
     } 
     theTread.interrupt(); 
    } 

} 
1

您可以使用AOP和jcabi-aspects一個@Timeable註釋(我是一個開發者):

@Timeable(limit = 1, unit = TimeUnit.SECONDS) 
String load(String resource) { 
    while (true) { 
    if (Thread.currentThread.isInterrupted()) { 
     throw new IllegalStateException("time out"); 
    } 
    // execution as usual 
    } 
} 

當達到時間限制你的線程會得到interrupted()標誌設置爲true和你的工作正確處理這種情況並停止執行。

此外,檢查這個博客帖子:http://www.yegor256.com/2014/06/20/limit-method-execution-time.html