Thursday, June 04, 2009

More on FutureTask

Adding to my previous FutureTask post: Future is a very nice interface, but the main problems with FutureTask are the lack of a callback and the clumsy constructor that requires a Callable. I guess their main use case was someone creating a FutureTask that performs a slow operation - as in my example, it is relatively easy to wrap the method in a Callable and then execute the FutureTask in a thread pool.

It is possible to add a callback by overriding FutureTask.done(), which is called after FutureTask.set().

There are few tricks to better use FutureTask. Let's say you have an operation that happens in background already, and you're notified with a callback. You want to wrap it in a Future to make it easier to use:




interface Callback {
void done(Object1);
}

void doSomethingAsync(Callback callWhenDone) {
}

class MyFuture extends FutureTask {
public MyFuture() {
// FutureTask _requires_ a callable - even if it's not using it. Let's give him a dummy one.
super(new Callable() { public Object1 call() { return null; }});
}
// set() is protected - need a visible method to let future know the result
public void gotTheResult(Object1 result) {
this.set(result);
}
}

Future<div class="youtube-video"><object1> getSomethingFuture() {
final MyFuture res = new MyFuture();
// We _don't_ submit it to an executor - so run() will not be called
doSomethingAsync(new Calback() {void done(Object1 result) {
// do what innerRun() does - i.e. call innerSet with the result.
// innerSet() will set state to RAN , even if the callable was never called.
res.gotTheResult(result);});
return res;
}