Lisa Anne
Lisa Anne

Reputation: 4595

Java multithreading: how to wait for a method to return a valid value

I am faced with the following situation in my Java app that use Threads.

I need to stop my thread and wait until otherObject.methodFoo() returns a NOT NULL value.

Something like this... (obviously this version does not work)

synchronized(otherObject.methodFoo())
{ 
    while (otherObject.methodFoo()==null)
    {
        otherObject.methodFoo().wait();
    }
    otherObject.methodFoo().nowCanDoStuff();
}

EDIT

To make things more complicate: otherObject.methodFoo() will return NOT NULL only when A DIFFERENT THREAD finishes his work

..so I will not be able to give to the 2 threads CountDownLatches or Semaphores...

Upvotes: 1

Views: 8262

Answers (4)

Rohit
Rohit

Reputation: 2152

Give COuntDownLatch a look. Especially the await() method.

update as per added info

public class OtherClass implements Runnable {
   CountDownLatch latch;
   test(Countdownlatch latch) { 
      this.latch = latch;
   }
   public void run(){
    latch.await(); //Block until latch is decreased in other thread.
    // does something.
   } 
}

public class SomeOtherClass implements Runnable {
   CountDownLatch latch;
   test(Countdownlatch latch) { 
      this.latch = latch;
   }
   public void run(){
    // does some other thing.
    latch.countDown(); //decrease the latch count.
   } 
}



public static void main(String[] args) {
    CountDownLatch latch = new CountDownLatch(1);
    OtherClass other = new OtherClass(latch);
    SomeOtherClass other = new SomeOtherClass(latch);
    //create threads and then start. 
}

Upvotes: 1

hemant1900
hemant1900

Reputation: 1226

If I understand your requirement correctly that you just want to stop the current thread until some method returns not null value then you can do something like this -

public class ThreadTest {

    public static void main(String[] args) {
        AtomicBoolean gotNotNullValue = new AtomicBoolean(false);
        AtomicBoolean done = new AtomicBoolean(false);

        FirstThread ft = new FirstThread();
        ft.setGotNotNullValue(gotNotNullValue);
        ft.setDone(done);

        SecondThread st = new SecondThread();
        st.setGotNotNullValue(gotNotNullValue);
        st.setDone(done);

        Thread t1 = new Thread(ft);
        Thread t2 = new Thread(st);
        t1.start();
        t2.start();
    }
}

class FirstThread implements Runnable {
    private int testCounter = 0;
    private AtomicBoolean gotNotNullValue;
    private AtomicBoolean done;

    public void setGotNotNullValue(AtomicBoolean gotNotNullValue) {
        this.gotNotNullValue = gotNotNullValue;
    }

    public void setDone(AtomicBoolean done) {
        this.done = done;
    }

    public void run() {
        while (!done.get()) {
            try {
                Thread.sleep(100);
            } catch (InterruptedException e) {
                // ignore
            }
            gotNotNullValue.set(methodFoo() != null);
            System.out.println("gotNotNullValue: " + gotNotNullValue + ", testCounter: " + testCounter);
        }
    }

    private Object methodFoo() {
        System.out.println("Inside methodFoo()");
        if (testCounter++ < 100) {
            return null;
        }
        return new Object();
    }
}

class SecondThread implements Runnable {
    private AtomicBoolean gotNotNullValue;
    private AtomicBoolean done;

    public void setGotNotNullValue(AtomicBoolean gotNotNullValue) {
        this.gotNotNullValue = gotNotNullValue;
    }

    public void setDone(AtomicBoolean done) {
        this.done = done;
    }

    public void run() {
        while (!gotNotNullValue.get()) {
            System.out.println("Got null value, waiting");
            try {
                Thread.sleep(100);
            } catch (InterruptedException e) {
                // ignore
            }
        }
        done.set(true);
        System.out.println("Got not null value, proceeding further");
    }
}

Upvotes: 1

Antonio Ortells
Antonio Ortells

Reputation: 337

How about not doing anything?

synchronized methodFoo()
{ 
    while (methodFoo()==null);
    methodFoo().nowCanDoStuff();
}

This loops forever until methodFoo() returns something other than null. Of course also your specific code loops forever due to recursion so do not call methodFoo() inside methodFoo(), so do something like:

synchronized otherMethodFoo()
{ 
    while (methodFoo()==null);
    methodFoo().nowCanDoStuff();
}

Also:

methodFoo().wait();

Is unclear. wait() is a method of a method? Or a method in the main object? or...

Upvotes: 2

Tommaso Bertoni
Tommaso Bertoni

Reputation: 2381

You can use java Semaphore's method acquire
Here a tutorial

Basically, semaphore.acquire(); blocks the program's flow until a permit is released with semaphore.release();
You can also specify the initial number of permits (in the constructor) and how many permits release in semaphore.release(3);.

You can imagine the permits as contained in a buffer and every time the acquire method is called, a permit is removed from the buffer. When there aren't any permits remained in it, the acquire call will be blocking, until another permit is released.

Upvotes: 1

Related Questions