Reputation: 4595
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
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
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
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
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