2

How can I break from a while loop after 20 seconds have passed? I want to avoid the use of threads.

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

    if (20secondsIsPassed) {
        break;
    }
}
Andronicus
  • 25,419
  • 17
  • 47
  • 88
Mateus Henrique
  • 428
  • 1
  • 5
  • 10
  • The simple way is to use [`System.currentTimeMillis`](https://docs.oracle.com/javase/8/docs/api/java/lang/System.html#currentTimeMillis--) to test the system clock. – Stephen C Apr 07 '19 at 05:26
  • Take a time before entering and then in each iteration take a time difference if the time difference more than 20 seconds, exit the while loop. – TAB Apr 07 '19 at 05:26
  • I don't know, but I am pretty sure implementing a timer without threads is impossible. Search up Timer and Timertask, I don't think it is very complicated. – Casimir Rönnlöf Apr 07 '19 at 05:27
  • @StephenC Would not `System.nanoTime()` be more appropriate to time a duration? – Slaw Apr 07 '19 at 05:28
  • Not unless the user needs (possibly) nanosecond resolution. (Also, read the weasel words in the javadoc.) But there are *many* solutions to this problem, with and without using threads explicitly or implicitly. – Stephen C Apr 07 '19 at 05:28
  • 1
    @StephenC I thought `currentTimeMillis` can return a value less than the previous invocation (maybe not likely, but possibly) depending on the underlying system clock which is why `nanoTime` should be used to measure a duration of time. – Slaw Apr 07 '19 at 05:32
  • OK ... maybe. However, neither `nanoTime()` or `currentTimeMillis()` is guaranteed by the javadoc to be monotically increasing. So you are really relying on the operating system **in both cases**. – Stephen C Apr 07 '19 at 05:37
  • @StephenC Fair enough, though [this answer](https://stackoverflow.com/questions/510462/is-system-nanotime-completely-useless/54566928#54566928) indicates `nanoTime` is monotonic (though doesn't say _increasing_) since Java 7. Given it's supposed to use the same origin for all invocations in the same JVM, should it not be impossible for the time to _decrease_? – Slaw Apr 07 '19 at 06:00
  • 1
    It should not be possible. However, system clocks can be "adjusted". And it is OS specific 1) whether adjustment is permitted for a given clock, and 2) whether an application will notice this. – Stephen C Apr 07 '19 at 06:03
  • 1
    https://www.goodreads.com/quotes/6344-time-is-an-illusion-lunchtime-doubly-so – Stephen C Apr 07 '19 at 06:08

2 Answers2

6

If you have if inside your while loop, that checks for time elapsed, then you won't have exactly 20 seconds, but at least 20s. The easiest way though is something like this:

LocalDateTime then = LocalDateTime.now();
while (true) {
    // logic
    if (ChronoUnit.SECONDS.between(then, LocalDateTime.now()) >= 20) break;
}
Andronicus
  • 25,419
  • 17
  • 47
  • 88
4

Simply by knowing that each second represent 1000 millisecond you can do the following calculation:

long seconds = System.currentTimeMillis();
    while (var && (seconds + (20 * 1000) > System.currentTimeMillis())) {
        // ...do something
    }
Ibrahim Ali
  • 1,237
  • 9
  • 20