Как остановить выполнение после определенного времени в Java? - PullRequest
23 голосов
/ 23 ноября 2010

В коде переменная timer будет указывать продолжительность, после которой завершается цикл while, например, 60 секунд.

Ответы [ 4 ]

45 голосов
/ 23 ноября 2010
long start = System.currentTimeMillis();
long end = start + 60*1000; // 60 seconds * 1000 ms/sec
while (System.currentTimeMillis() < end)
{
    // run
}
23 голосов
/ 31 марта 2012

вам следует попробовать новые Java Executor Services. http://docs.oracle.com/javase/6/docs/api/java/util/concurrent/ExecutorService.html

При этом вам не нужно программировать цикл измерения времени самостоятельно.

public class Starter {

    public static void main(final String[] args) {
        final ExecutorService service = Executors.newSingleThreadExecutor();

        try {
            final Future<Object> f = service.submit(() -> {
                // Do you long running calculation here
                Thread.sleep(1337); // Simulate some delay
                return "42";
            });

            System.out.println(f.get(1, TimeUnit.SECONDS));
        } catch (final TimeoutException e) {
            System.err.println("Calculation took to long");
        } catch (final Exception e) {
            throw new RuntimeException(e);
        } finally {
            service.shutdown();
        }
    }
}
3 голосов
/ 23 ноября 2010

Если вы не можете превысить свой лимит времени (это жесткий лимит), тогда нить - ваш лучший выбор.Вы можете использовать цикл для завершения потока, как только вы достигнете порога времени.Все, что происходит в этом потоке в данный момент, может быть прервано, что позволяет почти мгновенно останавливать вычисления.Вот пример:

Thread t = new Thread(myRunnable); // myRunnable does your calculations

long startTime = System.currentTimeMillis();
long endTime = startTime + 60000L;

t.start(); // Kick off calculations

while (System.currentTimeMillis() < endTime) {
    // Still within time theshold, wait a little longer
    try {
         Thread.sleep(500L);  // Sleep 1/2 second
    } catch (InterruptedException e) {
         // Someone woke us up during sleep, that's OK
    }
}

t.interrupt();  // Tell the thread to stop
t.join();       // Wait for the thread to cleanup and finish

Это даст вам разрешение примерно до 1/2 секунды.Путем более частого опроса в цикле while вы можете получить это.

Запуск вашего runnable будет выглядеть примерно так:

public void run() {
    while (true) {
        try {
            // Long running work
            calculateMassOfUniverse();
        } catch (InterruptedException e) {
            // We were signaled, clean things up
            cleanupStuff();
            break;           // Leave the loop, thread will exit
    }
}

Обновление на основе ответа Дмитрия

Дмитрий указал TimerTask , что позволило бы вам избежать цикла.Вы можете просто выполнить вызов объединения, и настроенная вами TimerTask позаботится о прерывании потока.Это позволит вам получить более точное разрешение без необходимости опроса в цикле.

1 голос
/ 23 ноября 2010

Зависит от того, что делает цикл while.Если есть вероятность, что он будет блокироваться в течение длительного времени, используйте TimerTask, чтобы запланировать задачу для установки флага stopExecution, а также .interrupt() ваш поток.Цикл, он может сидеть вечно в ожидании ввода или блокировки (опять же, может не быть проблемой для вас).

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...