20

我有一个while循环,我希望它在一段时间后退出。

例如:

while(condition and 10 sec has not passed){

}
4

5 回答 5

40
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();
于 2013-11-01T12:56:48.877 回答
15

提出和接受的解决方案不会奏效。

它不会在 10 秒后停止循环。想象一下循环中的代码需要 20 秒来处理并在 9.9 秒时被调用。您的代码将在执行 29.9 秒后退出。

如果你想在 10 秒后完全停止,你必须在一个外部线程中执行你的代码,你将在一定的超时后终止。

现有的解决方案已经在这里那里提出

于 2013-11-01T13:33:50.977 回答
10

就像是:

long start_time = System.currentTimeMillis();
long wait_time = 10000;
long end_time = start_time + wait_time;

while (System.currentTimeMillis() < end_time) {
   //..
}

应该做的伎俩。如果您还需要其他条件,那么只需将它们添加到 while 语句中。

于 2013-11-01T12:56:26.130 回答
1

对于同步调用,您可以使用如下内容:

    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);
    }

于 2021-04-01T11:32:01.130 回答
0

不要使用这个

System.currentTimeMillis()-startTime

它可能会导致主机时间更改时挂起。更好地使用这种方式:

Integer i = 0;
            try {
                while (condition && i++ < 100) {
                    Thread.sleep(100);
                }
            } catch (InterruptedException e) {
                e.printStackTrace();
            }

(100*100 = 10 秒超时)

于 2016-03-09T12:55:02.780 回答