Waiting for an object to be initialized
java, wait
Solution
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()`&`notify()`:
(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!
Problem
I have an object that is being initialized in a separate thread. Initialization can take several seconds while a local DB is being populated. ``` SpecialAnalysis currentAnalysis = new SpecialAnalysis(params_here); ``` I'm trying to implement a "cancel" button, that sets the object's `isCancelled` boolean to true. What is the proper Java way to implement this? ``` while (currentAnalysis == null) { } currentAnalysis.cancel(); ``` This method freezes the program as it appears to have entered a computationally inefficient loop. Is this a case where I could use `Object.wait()`? My current bad/semi-successful solution is: ``` while (currentAnalysis == null) { Thread.sleep(500); } currentAnalysis.cancel(); ``` Thanks!