I'm working with a lib strangely designed this code basically has a Task
object withonComplete()
and onfail()
methods, both these methods are void so I cannot use return inside them.
I have tried to use an external variable updated inside the task onComplete()
and onfail()
using
mytask.wait();
return value;
with the intention to wait for the completion of the task and then return value but I get
java.lang.IllegalMonitorStateException: object not locked by thread before wait()
if I try something like
while(!mytask.isComplete(){}
to force the method to wait the completion
app totally freezes
How could I get the value at the completion of the task correctly?
java.lang.IllegalMonitorStateException: object not locked by thread before wait()
You are close but you are missing some synchronization. To do wait()
or notify()
you need to be in a synchronized
block.
If you wanted to write a task that returned some value, I would do something like the following. Sore the result in a field, update that field inside of synchronized
onComplete()
or onFail()
methods. Then your calling thread can use the waitForResult()
method to return it once it has finished.
public class MyTask implements Task {
private String result;
public synchronized void onComplete() {
result = "it worked";
// this is allowed because the method is synchronized
notify();
}
public synchronized void onFail() {
result = "it failed";
// this is allowed because the method is synchronized
notify();
}
public synchronized String waitForResult() {
// a while loop is a good pattern because of spurious wakeups
// also, it's important to realize that the job might have already
// finished so we should always test it _before_ we wait
while (result == null) {
wait();
}
return result;
}
}
The thread that is testing for everything to finish would then just need to do:
String result = myTask.waitForResult();
Hope this helps.