Reputation: 29530
Following code worked fine
abstract class FunctionRunnable<V> implements Runnable {
protected abstract V calculate();
private V result;
private Throwable thr;
public synchronized final void run() {
try {
result = calculate();
}
catch (Throwable thr) {
this.thr = thr;
}
}
public synchronized final V getResult() {
if (thr != null) {
throw new RuntimeException(thr);
}
return result;
}
}
...
final FunctionRunnable<Boolean> runnable = new FunctionRunnable<Boolean>() {
public Boolean calculate() {
return doCalculation();
}
private boolean doCalculation() {
...
}
});
SwingUtilities.invokeAndWait(runnable);
final Boolean resultObj = runnable.getResult();
final boolean result = resultObj.booleanValue();
until Apple released 1.6.0_31 for which users of our application sometimes are getting an NPE in the last line.
Do you see a bug in the code or do other people have found similar problems with this particular Java update?
Upvotes: 2
Views: 694
Reputation: 56
If you look in to the implementation of EventQueue.invokeAndWait you will see that it does not correctly handle spurious wakeup. It calls lock.wait() then does not check whether the runnable has actually finished executing - this means invokeAndWait can return before your runnable has finished executing!
For some reason, spurious wakeup has started happening with reasonable frequency in update 31 on mac os, exposing this long standing bug in EventQueue. I'm not sure what has changed, it doesn't happen in any other versions of Java.
We fixed this by implementing our own invokeAndWait method with a simple boolean check for completion of the runnable.
Upvotes: 3
Reputation: 11
I sometimes get NullPonterExeption.... weird
java version "1.6.0_31" Java(TM) SE Runtime Environment (build 1.6.0_31-b04-415-11M3635) Java HotSpot(TM) Client VM (build 20.6-b01-415, mixed mode)
Upvotes: 1
Reputation: 200148
My SSCCE:
public abstract class FunctionRunnable<V> implements Runnable {
private V result;
private Throwable thr;
protected abstract V calculate();
public synchronized final void run() {
try { result = calculate(); } catch (Throwable thr) { this.thr = thr; }
}
public synchronized final V getResult() {
if (thr != null) throw new RuntimeException(thr);
return result;
}
public static void main(String[] args) throws Exception {
final FunctionRunnable<Boolean> runnable = new FunctionRunnable<Boolean>() {
public Boolean calculate() { return doCalculation(); }
private boolean doCalculation() {
try { Thread.sleep(2000); } catch (InterruptedException e) {}
return false;
}};
SwingUtilities.invokeAndWait(runnable);
System.out.println(runnable.getResult().booleanValue());
}
}
My Java version:
$java -version
java version "1.6.0_31"
Java(TM) SE Runtime Environment (build 1.6.0_31-b04-415-11M3635)
Java HotSpot(TM) 64-Bit Server VM (build 20.6-b01-415, mixed mode)
Started, ran for 2 seconds, printed false
.
Upvotes: 3