Wait x seconds or until the condition becomes true

How to wait x seconds or until the condition becomes true? The condition should be checked periodically while waiting. I am currently using this code, but there should be a short function.

for (int i = 10; i > 0 && !condition(); i--) { Thread.sleep(1000); } 
+5
source share
4 answers

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

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

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

It is mainly aimed at testing, but makes a specific request to wait for an arbitrary condition specified by the caller, without explicit synchronization or sleep calls. If you do not want to use the library, just read the code to see how it does it.

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

+22
source

Have you thought about some classes from java.util.concurrent - for example, BlockingQueue? You can use:

 BlockingQueue<Boolean> conditionMet = new BlockingQueue<Boolean>; conditionMet.poll(10,TimeUnit.SECONDS); 

And then in the code that changes your condition, do the following:

 conditionMet.put(true); 

EDIT:

Another example of a java.util.concurrent form might be CountDownLatch:

 CountDownLatch siteWasRenderedLatch = new CountDownLatch(1); boolean siteWasRendered = siteWasRenderedLatch.await(10,TimeUnit.SECONDS); 

This way you will wait 10 seconds or until the latch reaches zero. To reach zero, you only need:

 siteWasRenderedLatch.countDown(); 

This way you will not need to use the locks that are needed in the example conditions provided by @Adrian. I think it's just simpler and more straightforward.

And if you don't like the names โ€œLatchโ€ or โ€œQueueโ€, you can always transfer them to your own class called ie LimitedTimeCondition:

 public class LimitedTimeCondition { private CountDownLatch conditionMetLatch; private Integer unitsCount; private TimeUnit unit; public LimitedTimeCondition(final Integer unitsCount, final TimeUnit unit) { conditionMetLatch = new CountDownLatch(1); this.unitsCount = unitsCount; this.unit = unit; } public boolean waitForConditionToBeMet() { try { return conditionMetLatch.await(unitsCount, unit); } catch (final InterruptedException e) { System.out.println("Someone has disturbed the condition awaiter."); return false; } } public void conditionWasMet() { conditionMetLatch.countDown(); } } 

And the use will be:

 LimitedTimeCondition siteRenderedCondition = new LimitedTimeCondition(10, TimeUnit.SECONDS); // ... // if (siteRenderedCondition.waitForConditionToBeMet()) { doStuff(); } else { System.out.println("Site was not rendered properly"); } // ... // in condition checker/achiever: if (siteWasRendered) { condition.conditionWasMet(); } 
+5
source

See Condition .

Conditions (also known as condition queues or condition variables) provide a means for one thread to pause execution (until it "waits") until it has notified the other thread that some state state may now be true. Since access to this general state information occurs in different streams, it must be protected, therefore, some form of binding is connected with the condition. The key property that awaits the condition is that it atomically releases the associated lock and pauses the current thread, like Object.wait.

The condition instance is associated with a lock. To get a Condition Instance for a particular lock instance, use its newCondition ().

EDIT:

+4
source

You might want to use something like the code below (where secondsToWait contains the maximum number of seconds you want to wait to see if condition() changes. Varialbe isCondetionMet will contain true if the condition was found or false if the time waiting for code in anticipation of this condition.

  long endWaitTime = System.currentTimeMillis() + secondsToWait*1000; boolean isConditionMet = false; while (System.currentTimeMillis() < endWaitTime && !isConditionMet) { isConditionMet = condition(); if (isConditionMet) { break; } else { Thread.sleep(1000); } } 
+1
source

Source: https://habr.com/ru/post/1200405/


All Articles