我有一个while循环,我希望它在经过一段时间后退出。
例如:
while(condition and 10 sec has not passed){
}
答案 0 :(得分:26)
long startTime = System.currentTimeMillis(); //fetch starting time
while(false||(System.currentTimeMillis()-startTime)<10000)
{
// do something
}
因此声明
(System.currentTimeMillis()-startTime)<10000
检查循环开始后是否为10秒或10,000毫秒。
修改强>
正如@Julien所指出的,如果你在while循环中的代码块需要花费很多时间,这可能会失败。因此使用ExecutorService将是一个不错的选择。
首先,我们必须实现Runnable
class MyTask implements Runnable
{
public void run() {
// add your code here
}
}
然后我们可以像这样使用ExecutorService,
ExecutorService executor = Executors.newSingleThreadExecutor();
executor.invokeAll(Arrays.asList(new MyTask()), 10, TimeUnit.SECONDS); // Timeout of 10 seconds.
executor.shutdown();
答案 1 :(得分:11)
建议和接受的解决方案无法解决问题。
10秒后它不会停止循环。想象一下,循环中的代码需要20秒才能处理,并在9.9秒时调用。您的代码将在执行29.9秒后退出。
如果你想在10秒后完全停止,你必须在一个外部线程中执行你的代码,你将在一定的超时后杀死它。
答案 2 :(得分:7)
类似的东西:
long start_time = System.currentTimeMillis();
long wait_time = 10000;
long end_time = start_time + wait_time;
while (System.currentTimeMillis() < end_time) {
//..
}
应该做的伎俩。如果您还需要其他条件,则只需将它们添加到while语句中。
答案 3 :(得分:0)
不要使用此
System.currentTimeMillis()-startTime
可能会导致主机时间变化挂起。 更好地使用这种方式:
Integer i = 0;
try {
while (condition && i++ < 100) {
Thread.sleep(100);
}
} catch (InterruptedException e) {
e.printStackTrace();
}
(100 * 100 = 10秒超时)
答案 4 :(得分:0)
对于同步调用,您可以使用以下方法:
private void executeSomeSyncronLongRunningProccess() {
Duration duration = Duration.ofSeconds(5);
Predicate<String> condition = x -> x.equals("success");
Supplier<String> codeToExecute = () -> {
//Your code to execute here
return "success";
};
try {
String s = runOrTimeout(duration, condition, codeToExecute);
} catch (ExecutionException e) {
LOGGER.error("During execution is error occurred", e);
throw new RuntimeException(e);
} catch (TimeoutException e) {
LOGGER.error("Failed to complete task in {} seconds.", duration.getSeconds());
throw new RuntimeException(e);
} catch (InterruptedException e) {
LOGGER.error("Failed to complete task in {} seconds.", duration.getSeconds());
throw new RuntimeException(e);
}
}
private String runOrTimeout(Duration timeout, Predicate<String> conditionOnSuccess, Supplier<String> codeToExecute) throws InterruptedException, ExecutionException, TimeoutException {
ExecutorService executorService = Executors.newSingleThreadExecutor();
Future<String> pollQueryResults = executorService.submit(() -> {
String result = null;
boolean isRunning = true;
while (isRunning) {
result = codeToExecute.get();
if (conditionOnSuccess.test(result)) {
isRunning = false;
}
}
return result;
});
return pollQueryResults.get(timeout.getSeconds(), TimeUnit.SECONDS);
}