Выход из цикла while через 20 секунд

Как я могу выйти из цикла while по прошествии 20 секунд? Я хочу избежать использования потоков.

while (var) {
    // ...do something

    if (20secondsIsPassed) {
        break;
    }
}

Самый простой способ — использовать System.currentTimeMillis для проверки системных часов.

Stephen C 07.04.2019 07:26

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

TAB 07.04.2019 07:26

Я не знаю, но я уверен, что реализовать таймер без потоков невозможно. Найдите Timer и Timetask, я не думаю, что это очень сложно.

Casimir Rönnlöf 07.04.2019 07:27

@StephenC Не будет ли System.nanoTime() более подходящим для определения продолжительности?

Slaw 07.04.2019 07:28

Нет, если только пользователю не требуется (возможно) наносекундное разрешение. (Кроме того, прочитайте ласковые слова в javadoc.) Но есть решения много для этой проблемы, с явным или неявным использованием потоков и без них.

Stephen C 07.04.2019 07:28

@StephenC Я думал, что currentTimeMillis может вернуть значение меньше, чем предыдущий вызов (может быть, маловероятно, но возможно) в зависимости от базовых системных часов, поэтому nanoTime следует использовать для измерения продолжительности времени.

Slaw 07.04.2019 07:32

ОК, может быть. Тем не менее, ни nanoTime(), ни currentTimeMillis() не гарантируются javadoc для монотического увеличения. Так что вы действительно полагаетесь на операционную систему в обоих случаях.

Stephen C 07.04.2019 07:37

@StephenC Достаточно справедливо, хотя этот ответ указывает, что nanoTime является монотонным (хотя и не говорит увеличение) начиная с Java 7. Учитывая, что предполагается использовать одно и то же происхождение для всех вызовов в одной и той же JVM, не должно ли это быть невозможным на время снижаться?

Slaw 07.04.2019 08:00

Это не должно быть возможно. Однако системные часы можно «настроить». И это зависит от ОС: 1) разрешена ли настройка для данных часов и 2) заметит ли это приложение.

Stephen C 07.04.2019 08:03
goodreads.com/quotes/…
Stephen C 07.04.2019 08:08
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
Как вычислять биты и понимать побитовые операторы в Java - объяснение с примерами
Как вычислять биты и понимать побитовые операторы в Java - объяснение с примерами
В компьютерном программировании биты играют важнейшую роль в представлении и манипулировании данными на двоичном уровне. Побитовые операции...
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Приходилось ли вам сталкиваться с требованиями, в которых вас могли попросить поднять тревогу или выдать ошибку, когда метод Java занимает больше...
Полный курс Java для разработчиков веб-сайтов и приложений
Полный курс Java для разработчиков веб-сайтов и приложений
Получите сертификат Java Web и Application Developer, используя наш курс.
1
10
2 461
2
Перейти к ответу Данный вопрос помечен как решенный

Ответы 2

Ответ принят как подходящий

Если у вас есть if внутри цикла while, который проверяет прошедшее время, то у вас будет не ровно 20 секунд, а по меньшей мере 20 секунд. Хотя самый простой способ примерно такой:

LocalDateTime then = LocalDateTime.now();
while (true) {
    // logic
    if (ChronoUnit.SECONDS.between(then, LocalDateTime.now()) >= 20) break;
}

Это даст вам как минимум 21 секунду. Вместо этого используйте >= и более точную единицу измерения времени.

Torben 07.04.2019 08:05

Просто зная, что каждая секунда представляет собой 1000 миллисекунд, вы можете сделать следующий расчет:

long seconds = System.currentTimeMillis();
    while (var && (seconds + (20 * 1000) > System.currentTimeMillis())) {
        // ...do something
    }

Другие вопросы по теме