Как я могу выйти из цикла while по прошествии 20 секунд? Я хочу избежать использования потоков.
while (var) {
// ...do something
if (20secondsIsPassed) {
break;
}
}
Возьмите время перед входом, а затем в каждой итерации возьмите разницу во времени, если разница во времени более 20 секунд, выйдите из цикла while.
Я не знаю, но я уверен, что реализовать таймер без потоков невозможно. Найдите Timer и Timetask, я не думаю, что это очень сложно.
@StephenC Не будет ли System.nanoTime()
более подходящим для определения продолжительности?
Нет, если только пользователю не требуется (возможно) наносекундное разрешение. (Кроме того, прочитайте ласковые слова в javadoc.) Но есть решения много для этой проблемы, с явным или неявным использованием потоков и без них.
@StephenC Я думал, что currentTimeMillis
может вернуть значение меньше, чем предыдущий вызов (может быть, маловероятно, но возможно) в зависимости от базовых системных часов, поэтому nanoTime
следует использовать для измерения продолжительности времени.
ОК, может быть. Тем не менее, ни nanoTime()
, ни currentTimeMillis()
не гарантируются javadoc для монотического увеличения. Так что вы действительно полагаетесь на операционную систему в обоих случаях.
@StephenC Достаточно справедливо, хотя этот ответ указывает, что nanoTime
является монотонным (хотя и не говорит увеличение) начиная с Java 7. Учитывая, что предполагается использовать одно и то же происхождение для всех вызовов в одной и той же JVM, не должно ли это быть невозможным на время снижаться?
Это не должно быть возможно. Однако системные часы можно «настроить». И это зависит от ОС: 1) разрешена ли настройка для данных часов и 2) заметит ли это приложение.
Если у вас есть if
внутри цикла while
, который проверяет прошедшее время, то у вас будет не ровно 20 секунд, а по меньшей мере 20 секунд. Хотя самый простой способ примерно такой:
LocalDateTime then = LocalDateTime.now();
while (true) {
// logic
if (ChronoUnit.SECONDS.between(then, LocalDateTime.now()) >= 20) break;
}
Это даст вам как минимум 21 секунду. Вместо этого используйте >= и более точную единицу измерения времени.
Просто зная, что каждая секунда представляет собой 1000 миллисекунд, вы можете сделать следующий расчет:
long seconds = System.currentTimeMillis();
while (var && (seconds + (20 * 1000) > System.currentTimeMillis())) {
// ...do something
}
Самый простой способ — использовать
System.currentTimeMillis
для проверки системных часов.