如果超过3秒,我想超时执行一个函数。
long startTime = System.currentTimeMillis();
getStaticJsonResponse("build", "post");
long finishTime = System.currentTimeMillis();
long elapsedTime = finishTime - startTime / 1000;
System.out.println("time" + elapsedTime);
答案 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;
这应该有用。