如何检查函数执行是否超过指定的秒数?

时间:2012-02-21 09:19:13

标签: java

如果超过3秒,我想超时执行一个函数。

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

5 个答案:

答案 0 :(得分:10)

您需要有一个单独的线程,等待方法终止或超时。幸运的是,伟大的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);

(假设您的方法返回一个String,否则调整返回类型)。

请注意,与其他解决方案一样,这可以保证呼叫者最多等待3次。但它确实不能保证方法执行在3秒后实际中止。只有在被调用的代码对Thread.interrupt()完成的线程中断作出反应时才会中止它。等待I / O的所有函数都这样做,但您自己的代码可能没有。

答案 1 :(得分: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()方法,这会导致InterruptedException JSONRequester run()被抛出1}}方法,从而终止任务线程。'

编辑:我应该注意,这假设getStaticJsonResponse()中的代码,特别是,线程阻塞的任何地方都满足here列出的条件之一用于回复interrupt()电话。但是,在网络代码中(如图所示),这通常是一个非常安全的假设。

答案 2 :(得分:0)

创建一个Timeout课程。使用表示所需秒数的参数构造它。给它一个HasTimedOut成员函数。定期在函数中调用此成员,如果它返回true,则从函数返回。

答案 3 :(得分: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秒(但对于基本超时足够接近),并且在现实世界的情况下,检查中断应该检查是否有一些(线程安全的,即易失性)变量设置也是如此,因为中断可能是从另一个线程触发的(但这超出了这个答案的范围)。

答案 4 :(得分:-1)

只需更改

long elapsedTime = finishTime - startTime / 1000;

long elapsedTime = (finishTime - startTime) / 1000;

这应该有用。