Is there a library in Java that does the following? A thread
should repeatedly sleep
for x milliseconds until a condition becomes true or the max time is reached.
This situation mostly occurs when a test waits for some condition to become true. The condition is influenced by another thread
.
[EDIT]Just to make it clearer, I want the test to wait for only X ms before it fails. It cannot wait forever for a condition to become true. I am adding a contrived example.
class StateHolder{
boolean active = false;
StateHolder(){
new Thread(new Runnable(){
public void run(){
active = true;
}
}, "State-Changer").start()
}
boolean isActive(){
return active;
}
}
class StateHolderTest{
@Test
public void shouldTurnActive(){
StateHolder holder = new StateHolder();
assertTrue(holder.isActive); // i want this call not to fail
}
}
Wait() method releases lock during Synchronization. Sleep() method does not release the lock on object during Synchronization. Wait() should be called only from Synchronized context.
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.
The wait() method causes the current thread to wait until another thread invokes the notify() or notifyAll() methods for that object. The notify() method wakes up a single thread that is waiting on that object's monitor. The notifyAll() method wakes up all threads that are waiting on that object's monitor.
In java, synchronized methods and blocks allow only one thread to acquire the lock on a resource at a time. So, when wait() method is called by a thread, then it gives up the lock on that resource and goes to sleep until some other thread enters the same monitor and invokes the notify() or notifyAll() method.
EDIT
Most answers focus on the low level API with waits and notifies or Conditions (which work more or less the same way): it is difficult to get right when you are not used to it. Proof: 2 of these answers don't use wait correctly.java.util.concurrent
offers you a high level API where all those intricacies have been hidden.
IMHO, there is no point using a wait/notify pattern when there is a built-in class in the concurrent package that achieves the same.
A CountDownLatch with an initial count of 1 does exactly that:
latch.countdown();
boolean ok = latch.await(1, TimeUnit.SECONDS);
Contrived example:
final CountDownLatch done = new CountDownLatch(1);
new Thread(new Runnable() {
@Override
public void run() {
longProcessing();
done.countDown();
}
}).start();
//in your waiting thread:
boolean processingCompleteWithin1Second = done.await(1, TimeUnit.SECONDS);
Note: CountDownLatches are thread safe.
Awaitility offers a simple and clean solution:
await().atMost(10, SECONDS).until(() -> condition());
You should be using a Condition
.
If you would like to have a timeout in addition to the condition, see await(long time, TimeUnit unit)
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With