如何在Java中实现进程的超时



我想为进程实现一个超时,如果它花费的时间超过X秒,我希望它停止并执行返回语句。在我的现实世界中,我将调用一个REST API,apiCallController((表示控制器。

不管怎样,我在下面尝试的一切都会继续执行。

我该如何做到这一点?

编辑:如果我试图实现的目标奏效,长期运行的任务将无法完成,这意味着线

System.out.println("End http/SSH stuff...");

永远不会打印,并且这行

response = "Call successful...";

也不会执行,将响应变量保留为最初初始化的

String response = "Call aborted...";

但我仍然需要在超时后返回响应

我已经在这个Java fiddle中进行了测试(您可以直接粘贴代码(:https://javafiddle.leaningtech.com/

谢谢。

import java.util.*;
import java.lang.*;
public class JavaFiddle
{
public static void main(String[] args)
{
String response = apiCallController();
System.out.println(response);
}

public static String apiCallController() {
System.out.println("creepy...n");
int timeoutSeconds = 2;
int longRunningTaskDurationSeconds = 5;
String response = "Call aborted...";
try 
{
new Timer().schedule( 
new TimerTask() {
@Override
public void run() {
System.out.println("Timeout reached, aborting... (This is where I want everything to stop without killing JVM/Tomcat)");
// System.exit(0); This guy shut tomcat down x_X
return;
}
}, 
timeoutSeconds * 1000
);

System.out.println("Start http/SSH stuff...");
Thread.sleep(longRunningTaskDurationSeconds * 1000);
System.out.println("End http/SSH stuff...");

response = "Call successful...";
} 
catch(InterruptedException e)
{
System.out.println(e);
}
System.out.println("npasta...");

return "n" + response;
}

}

编辑2:根据公认的答案,我只是重构了一个触摸:

import java.util.*;
import java.lang.*;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.Callable;
import java.util.concurrent.Future;
import java.util.concurrent.TimeoutException;
import java.util.concurrent.ExecutionException;
public class JavaFiddle
{
public static void main(String[] args)
{
System.out.println("creepy...nn");
String response = apiCallController();
System.out.println(response);
System.out.println("nnpasta...");

}

public static String apiCallController() {
String response = "Stuff TIMED out...";
ScheduledExecutorService executor = Executors.newSingleThreadScheduledExecutor();
Callable<String> r = () -> {
try {
System.out.println("Start http/SSH stuff...");
TimeUnit.SECONDS.sleep(5);
System.out.println("End http/SSH stuff...");
return "Stuff COMPLETED successfully...";
} catch (InterruptedException e) {
throw e;
}
};
Future<String> task = executor.submit(r);
try {
response = task.get(3, TimeUnit.SECONDS);
} catch(InterruptedException | TimeoutException e) {
task.cancel(true);
} catch (ExecutionException e) {
e.printStackTrace();
}
// Need to shutdown executor (think of it is master thread here)
// You may want to control this behaviour outside of this function call
executor.shutdown();
return "n" + response;
}

}

您的任务在打印到控制台后完成,但您的计时器正在等待更多任务,因此仍在运行,并且由于它仍在运行main函数,因此不会退出。

如果您没有进一步的任务,您需要cancel您的计时器。

try
{
Timer timer = new Timer();
timer.schedule(
new TimerTask() {
@Override
public void run() {
System.out.println("Timeout reached, aborting... (This is where I want everything to stop without killing JVM/Tomcat)");
}
},
timeoutSeconds * 1000
);
System.out.println("Start http/SSH stuff...");
Thread.sleep(longRunningTaskDurationSeconds * 1000);
System.out.println("End http/SSH stuff...");
response = "Call successful...";
timer.cancel();
}
catch(InterruptedException e)
{
System.out.println(e);
}
System.out.println("npasta...");
return "n" + response;

编辑

由于问题是用真实用例更新的,我在这里添加了一个编辑,以建议该用例的答案(前面的部分现在可能与问题无关(。

这是我解决你问题的办法,看看吧。我使用了FutureScheduledExecutorService来实现它

public static String apiCallController() {
System.out.println("creepy...n");

String response = "Call aborted...";
ScheduledExecutorService executor = Executors.newSingleThreadScheduledExecutor();
Callable<String> r = () -> {
try {
// To mimick the actual call
TimeUnit.SECONDS.sleep(5);
System.out.println("call successful...");
return "Some response";
} catch (InterruptedException e) {
System.out.println("Timeout reached, aborting... (This is where I want everything to stop without killing JVM/Tomcat)");
throw e;
}
};
Future<String> task = executor.submit(r);
try
{
System.out.println("Start http/SSH stuff...");

//Let's just wait for 3 secs for response to arrive
response = task.get(3, TimeUnit.SECONDS);
System.out.println("End http/SSH stuff...");
response = "Call successful...";
}
catch(InterruptedException | TimeoutException e)
{
// cancelling a task, either it was interrupted (sleep call can be interrupted) or its timeout
task.cancel(true);
}catch (ExecutionException e) {
//Something went wrong horribly
e.printStackTrace();
}
System.out.println("npasta...");
// Need to shutdown executor (think of it is master thread here)
// You may want to control this behaviour outside of this function call
executor.shutdown();
return "n" + response;
}

相关内容

  • 没有找到相关文章

最新更新