About Abhishek Gupta

Java EE: Asynchronous constructs and capabilities

Introduction

Java EE has a number of APIs and constructs to support Asynchronousexecution. This is vital from a scalability and performance stand point.

Let us assume 2 modules which are interacting with each other. When moduleA (the sender) sends a message to moduleB (the receiver) in a Synchronous fashion, the communication takes place in the context of a Single thread i.e. the thread which initiated the communication from moduleA is blocked until moduleB responds back.

This was a generic statement but can be extended to the context of a simple Java methods interacting with each other – in this case, a synchronous call from methodA to methodB would execute in the samethread which would be blocked until methodB returns or throws an exception.

Why do we need Asynchronous behavior in Java EE based applications?

We can further extrapolate this point to the Java EE world – be it inter server communication e.g. between web tier and EJB tier (servlets and EJBs) or a typical client server interaction – a browser interacting with a RESTful end point, Servlets etc – the server thread which responds to a client request always blocks until the server component responds back.

Here is where Asynchronous execution comes into play – if the server thread processing the client request can be released/suspended and the actual business logic is executed in a separate thread (different than that of the original one), performance and scalability can be improved immensely ! E.g. if a HTTP listener thread allocated to listen to client requests is released immediately, then it is free to attend to requests from other clients and the business logic can be executed in a separate container thread which can then return the response via appropriate methods such as java.util.concurrent.Future object or via call back handlers registered by the client. Think from an end user perspective – responsiveness matters a lot!

Dive In: Async constructs and APIs in Java EE

Let’s take a look at few of the Async related features (APIs) in Java EE. This is not an exhaustive list – but should be a good starting point.

Note: The code presented below is in a snippet form (for obvious reasons). The complete samples can be accessed here.

JAX-RS 2.0

Async processing of requests is a new feature in 2.0 edition of JAX-RS (new in Java EE 7). In order to execute an aysnc request using JAX-RS APIs, one needs to inject a reference to a javax.ws.rs.container.AsyncResponse interface in the JAX-RS resource method itself. This parameter puts the request execution in async mode and the method proceeds with its execution. The resumemethod on the AsynResponse object needs to be called from within a separate thread after the business logic execution is complete. One can leverage the Java EE concurrency utility features (discussed later) such as the javax.enterprise.concurrent.ManagedExecutorService in order to encapsulate the business logic as a Runnable object and submitting it to the container’s executor service which takes care of the rest. No need to spawn un-managed, isolated threads on your own.

The JAX-RS Client API also has asynchronous capabilities but they have not been discussed in the post. They are definitely worth a look!

Websocket 1.0

The Websocket API is a brand new addition to the Java EE arsenal (introduced in Java EE 7). It facilitates bi-directional (both server and client initiated) communication which is also full duplex in nature (either the client or server can send messages to each other at any time).

In order to send async messages using the Websocket API, one needs to use the getAsyncRemotemethod available on the javax.websocket.Session interface. Internally, this is nothing but an instance of the nested interface of the javax.websocket.RemoteEnpoint – javax.websocket.RemoteEnpoint.Async. Calling the regular sendXXXmethods on this would result in the sending process being executed in a separate thread. This is particularly useful when you consider exchange of large messages or handling large numbers of websocket clients to whom the messages need to be sent. The method wither returns a java.util.concurrent.Future object or one can register a callback in the form of a javax.websocket.SendHandler interface implementation.

Concurrency Utilities 1.0

The Java EE Concurrency Utilities is another great addition to Java EE 7. It provides a standard way of spawning threads – the good part is that these are container managed and not just isolated/orphan threads about which the container has no contextual information.

In general, the Concurrency Utilities 1.0 provide a few standard constructs for execution of asynchronous tasks in separate threads. These are as follows – javax.enterprise.concurrent.ManagedExecutorService and javax.enterprise.concurrent.ManagedScheduledExecutorService.

In order to start a new task in a separate thread, one can use the ManagedExecutorService interface to submit a Runnable. In addition to implementing the Runnable interface, a class can also implement the javax.enterprise.concurrent.ManagedTask interface and provide a javax.enterprise.concurrent.ManagedTaskListener implementation in order to listen to life cycle changes to the task submitted via the ManagedExecutorService.

Servlet 3.0

Asynchronous HTTP was introduced in Servlet 3.0 (part of Java EE 6) which basically provided the capability to execute the request in separate thread and suspend the original thread which handled the client invocation.

The key player here is the javax.servlet.AsyncContext interface. In order to initiate asynchronous processing, the startAsyncmethod of the java.servlet.ServletRequest interface is called. In order to execute the core logic, a java.lang.Runnable object needs to be submitted to the start method of the AsyncContext interface. One can choose to attach a listener by implementing the javax.servlet.AsyncListener in order to receive callback notifications during specific times of the Async task execution.

EJB 3.1

Typically, (prior to EJB 3.1) EJB Message Driven Beans were used to fulfill async related requirements. A MDB bean listens to messages sent to a javax.jms.Destination (a Queue or Topic) and executes the required business logic – this might be anything from sending an email to initiating an order processing task. The important thing to understand is that the client which sends the message to the Queue in the first place is unaware of the MDB (decoupled) and does not have to wait/remain blocked until the end of the job (email receipt or order processing confirmation).

EJB 3.1 (part of Java EE 6) introduced the javax.ejb.Asynchronous annotation. This can be placed on a EJB Session bean (Stateless, Stateful or Singleton) class (makes all the methods Asynchronous) or at the method level itself – in case fine grained control is needed. A method with the @Asynchronous annotation can either return void (fire and forget) or an instance of java.util.concurrent.Future if the async method result needs to be tracked – this can be done by calling the Future.get() – the thing to note is that the getmethod itself is blocking in nature.

This was a rather brief preview of Java EE capabilities. These APIs and specifications are functionally rich and it is hard cover all of them via a blog post! I hope this piques your interest and gives you a starting point to explore further.

Join Us

With 1,240,600 monthly unique visitors and over 500 authors we are placed among the top Java related sites around. Constantly being on the lookout for partners; we encourage you to join us. So If you have a blog with unique and interesting content then you should check out our JCG partners program. You can also be a guest writer for Java Code Geeks and hone your writing skills!

Disclaimer

All trademarks and registered trademarks appearing on Java Code Geeks are the property of their respective owners. Java is a trademark or registered trademark of Oracle Corporation in the United States and other countries. Examples Java Code Geeks is not connected to Oracle Corporation and is not sponsored by Oracle Corporation.