So, this is version 2 of this post, because the old one was way too less explaining and way too much reinventing the wheel.

As I want to have a nice way to execute code asynchronously and have a callback of the result afterwards, I was happy to learn about lambdas , functional interfaces and method references

There are tons of functional interfaces coming with the lambdas. A lot of them, which can be used for method references, are in the java.util.function package.

So I want to have my Async Callback functionality the following way:

  • I want to have a method without parameters, returning my expected Object.
    This method needs to run asynchronously.
  • The asynchronous functionality will be provided by an ExecutorService, which executes
    a Callable<T>  object, and gets a Future<T>.
  • After the asynchronous method is finished, I want to execute the callback method, which receives
    two parameters and returns nothing.

    • Parameter 1 will be an Exception, which will be the Exception coming from my asynchronous method.
      (To be specific, it’s the Exception, if future.get()  throws an exception)
    • Parameter 2 will be the object T,to be specific, the result from the asynchronous method.

 

Alright, let’s have a look into two functional interfaces we can use for our asynchronous call and for the callback.

Callable<T> is the functional interfaces we use for our asynchronous method. It returns an object of type T and receives no parameters.

These are three ways of calling a Callable<String> :

As you can see, the old way is to create an anonymous class and overwrite the call() method.

The new way with the lambda looks more intuitive, in my opinion. You create a lambda expression, which does not get any parameters () and in the execution code you just return a string.

For the method reference, you have to create a method, which itself has the same structure, as the functional interface would expect.
So the method structure has to return a String and must not receive any parameters: public static String methodName()

If the method fulfils the criteria, you can use the new double colon (::) syntax to let the compiler know which method you want to reference to.
Callable<String> c3 = Main::methodReference;

 

For the callback, we want to use an functional interface, which does not return anything (void) and receives two parameters.

The java.util.function package contains such an interface. It’s called BiConsumer<T,S>.

Again, three ways to use this interface.

It’s kind of the same. Every way executes the same code, but the important part is how we can use the lambda and the method reference.

 

But how does this help us with our asynchronous callback problem?

Therefore we create a new method, which has 3 parameters.

  1. The first one is the ExecutorService, which we need to execute the code asynchronously.
  2. The second is the Callable<T> method referencelambda or anonymous class.
  3. The third is the BiConsumer<Exception,T> method reference, lambda or anonymous class.

This method uses the ExecutorService to call a Runnable, in which we can execute our asynchronous call and wait for the result. And afterwards we can call the callback.
(We use the new lambda way to create the Runnable here)

 

Alright, so looking into the code we can see how everything works.
We create a Future<T> and call the callable asynchronously. We try to get the result of the future and execute the callback either with our error or with the result.

But how do we use this method? Have a look into the full listing, containing this method and one method for the callable as well as one for the callback. Those two methods will be passed with the method reference way.

 

We now call our method asynchronously and get a feedback via our callback method.  I think this listing should be self explaining.

 

Feel free to leave a comment below and ask any questions.

– Loki

Asynchronous Methods using Java 1.8 and Lambdas
Tagged on:                     

Leave a Reply

Your email address will not be published. Required fields are marked *