why not both Future and CompletionHandler?

Wolfgang Baltes wolfgang.baltes at laposte.net
Fri Apr 15 15:34:39 PDT 2011


On 2011-04-15 13:19, Jitendra Kotamraju wrote:
>
> There is also similar API ListenableFuture [1] in Guava libraries.  I 
> haven't seen the CompletionFuture, but I guess it can be subtype of 
> ListenableFuture. Regardless of NIO2, it would be good have this API 
> in SE and it will be quite useful to JAX-RS/JAX-WS API.
>
> Jitu
> [1]http://guava-libraries.googlecode.com/svn-history/r224/trunk/javadoc/com/google/common/util/concurrent/ListenableFuture.html 
>
>
>
Thanks for pointing this out. ListenableFuture is certainly of interest 
in this context. However, there is at least one significant difference: 
CompletionFuture chains a Future behind a CompletionHandler, whereas 
ListenableFuture chains Futures. At this time, CompletionFuture is used 
to launch only one Future, but this could easily be changed.

I am not sure CompletionFuture should be in the SE API; I think it is 
more a pattern with many implementation options and variations due to 
the coupling (see below how the Throwable is forwarded). 
ListenableFuture is more generic and probably fits as an API. This is 
because there is no coupling between the Future and the listeners.

Here is some code that indicates how CompletionFuture works.

     public class
     CompletionFuture<V, A , FV>
extends FutureTask<FV>
     implements CompletionHandler<V, A> {

final private ExecutorService exec;

     public CompletionFuture(Callable<FV> task, ExecutorService exec) {
     super(task);
         this.exec = exec;
}

     @Override
public void completed(V result, A attachment) {
// Do something with result and/or attachment.
         // Chain the task.
     this.exec.execute(this);
     }

     @Override
public void failed(Throwable t, A attachment) {
// Shortcut the task and send t instead.
         this.setException(t);
}
}

simplified example calling code:

     Callable<FV> task = new Callable() {
         @Override
         public FV call() throws Exception {
             // insert code here
         }
     };
     CompletionFuture cf = new CompletionFuture(task, exec);
     AsynchronousFileChannel asf = new AsynchronousFileChannel();
     asf.open(...);
     ByteBuffer bb = ByteBuffer.allocateDirect(capacity);
     asf.read(bb, position, null, cf);
     FV result = cf.get();

Wolfgang.





More information about the nio-dev mailing list