You should use a proper wait event (see the Guarded Block tutorial), otherwise you run the risk of the "watching" thread seeing the reference before it sees completely initialized member fields of the Card
. Also wait()
will allow the thread to sleep instead of sucking up CPU in a tight while loop.
For example:
Class A {
private final Object cardMonitor = new Object();
private volatile Card myCard;
public void keepCheck () {
synchronized (cardMonitor) {
while (myCard == null) {
try {
cardMonitor.wait();
} catch (InterruptedException x) {
// either abort or ignore, your choice
}
}
}
callAnotherMethod();
}
public void run () {
synchronized (cardMonitor) {
myCard = new Card(5);
cardMonitor.notifyAll();
}
}
}
I made myCard
private in the above example. I do recommend avoiding lots of public fields in a case like this, as the code could end up getting messy fast.
Also note that you do not need cardMonitor
-- you could use the A
itself, but having a separate monitor object lets you have finer control over synchronization.
Beware, with the above implementation, if run()
is called while callAnotherMethod()
is executing, it will change myCard
which may break callAnotherMethod()
(which you do not show). Moving callAnotherMethod()
inside the synchronized block is one possible solution, but you have to decide what the appropriate strategy is there given your requirements.