Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Sleep and check until condition is true

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 
    }
}
like image 677
Rag Avatar asked Jan 22 '13 17:01

Rag


People also ask

What is the difference between sleep and wait method?

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.

How wait method works 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.

How wait notify works?

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.

How to implement wait in Java?

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.


3 Answers

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:

  • When the condition becomes true, call latch.countdown();
  • in your waiting thread, use : 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.

like image 135
assylias Avatar answered Oct 09 '22 04:10

assylias


Awaitility offers a simple and clean solution:

await().atMost(10, SECONDS).until(() -> condition());
like image 32
thisismydesign Avatar answered Oct 09 '22 05:10

thisismydesign


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)

like image 8
Alex DiCarlo Avatar answered Oct 09 '22 05:10

Alex DiCarlo