Firstly, yes Object.wait()
and Object.notify()
/ Object.notifyAll()
are what you need. Whether or not you use them directly is a different matter. Due to the ease of making mistakes programming directly with wait/notify
it is generally recommended to use the concurrency tools added in Java 1.5 (see second approach below).
The traditional wait/notify
approach:
Initialisation:
synchronized (lockObject) {
SpecialAnalysis currentAnalysis = new SpecialAnalysis(params_here);
lockObject.notifyAll();
}
In the 'cancel' thread:
synchronized (lockObject) {
while (currentAnalysis == null) {
try { lockObject.wait(); }
catch Exception(e) { } // FIXME: ignores exception
}
}
currentAnalysis.cancel();
Of course these could be synchronized methods instead of blocks. Your choice of lockObject
will depend on how many 'cancel' threads you need etc. In theory it could be anything, i.e. Object lockObject = new Object();
as long as you are careful the correct threads have access to it.
Note that it is important to put the call to wait()
in a while loop here due to the possibility of spurious wakeups coming from the underlying OS.
A simpler approach would be to use a CountDownLatch
, sparing you from the nuts and bolts of wait()
¬ify()
:
(I'm making a couple of assumptions here in order to suggest a possibly cleaner approach).
class AnalysisInitialiser extends Thread {
private CountDownLatch cancelLatch = new CountDownLatch(1);
private SpecialAnalysis analysis = null;
@Override
public void run() {
analysis = new SpecialAnalysis(params);
cancelLatch.countDown();
}
public SpecialAnalysis getAnalysis() {
cancelLatch.await();
return analysis;
}
}
Then in the thread that needs to send the cancel signal: (obviously you need to get hold of the AnalysisInitialiser
object in some way)
analysisInit.getAnalysis.cancel();
No concurrency primitive boilerplate, yay!