Java多线程:如何等待方法返回有效值

时间:2015-03-13 10:17:09

标签: java multithreading

我在使用Threads的Java应用程序中面临以下情况。

我需要停止我的主题并等待,直到otherObject.methodFoo()返回 NOT NULL 值。

像这样......(显然这个版本不起作用)

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

修改

使事情变得更复杂:otherObject.methodFoo()仅在A DIFFERENT THREAD完成工作时才会返回NOT NULL

..所以我无法给2个线程CountDownLatches或Semaphores ...

4 个答案:

答案 0 :(得分:1)

您可以使用java Semaphore的方法acquire
Here a tutorial


基本上,semaphore.acquire();会阻止程序的流程,直到semaphore.release();发布许可证为止 您还可以指定初始许可数量(在构造函数中)以及semaphore.release(3);中允许的许可数量。

您可以想象缓冲区中包含的许可证,并且每次调用acquire方法时,都会从缓冲区中删除许可证。如果没有任何许可证,acquire电话将被阻止,直到另一个许可证被释放。

答案 1 :(得分:1)

COuntDownLatch看一看。特别是await()方法。

根据添加的信息进行更新

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. 
}

答案 2 :(得分:1)

怎么不做任何事情?

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

这将永远循环,直到methodFoo()返回null以外的其他内容。当然,由于递归,您的特定代码也会永远循环,因此不要在methodFoo()中调用methodFoo(),所以请执行以下操作:

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

另外:

methodFoo().wait();

目前尚不清楚。 wait()是一个方法的方法?还是主要对象中的方法?或...

答案 3 :(得分:1)

如果我理解你的要求你只想停止当前线程,直到某个方法返回非null值,那么你可以这样做 -

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");
    }
}