Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

wait x seconds or until a condition becomes true

Tags:

How to wait x seconds or until a condition becomes true? The condition should be tested periodically while waiting. Currently I'm using this code, but there should be a short function.

for (int i = 10; i > 0 && !condition(); i--) {     Thread.sleep(1000); } 
like image 956
user3561614 Avatar asked Aug 15 '14 11:08

user3561614


People also ask

How do you create a wait method in Java?

wait() causes current thread to wait until another thread invokes the notify() method or the notifyAll() method for this object. In other words, this method behaves exactly as if it simply performs the call wait(0). The current thread must own this object's monitor.


2 Answers

Assuming you want what you asked for, as opposed to suggestions for redesigning your code, you should look at Awaitility.

For example, if you want to see if a file will be created within the next 10 seconds, you do something like:

await().atMost(10, SECONDS).until(() -> myFile.exists()); 

It's mainly aimed at testing, but does the specific requested trick of waiting for an arbitrary condition, specified by the caller, without explicit synchronization or sleep calls. If you don't want to use the library, just read the code to see the way it does things.

Which, in this case, comes down to a similar polling loop to the question, but with a Java 8 lambda passed in as an argument, instead of an inline condition.

like image 62
soru Avatar answered Oct 07 '22 23:10

soru


I didn't find a solution in the JDK. I think this feature should be added to the JDK.

Here what I've implemented with a Functional Interface:

import java.util.concurrent.TimeoutException; import java.util.function.BooleanSupplier;  public interface WaitUntilUtils {    static void waitUntil(BooleanSupplier condition, long timeoutms) throws TimeoutException{     long start = System.currentTimeMillis();     while (!condition.getAsBoolean()){       if (System.currentTimeMillis() - start > timeoutms ){         throw new TimeoutException(String.format("Condition not met within %s ms",timeoutms));       }     }   } } 
like image 34
Tama Avatar answered Oct 08 '22 01:10

Tama