我在使用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 ...
答案 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");
}
}