2012-02-21 55 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的函数都这样做,但你自己的代码可能不会。

相关问题