Free Online Courses for Software Developers - MrBool
× Please, log in to give us a feedback. Click here to login
×

You must be logged to download. Click here to login

×

MrBool is totally free and you can help us to help the Developers Community around the world

Yes, I'd like to help the MrBool and the Developers Community before download

No, I'd like to download without make the donation

×

MrBool is totally free and you can help us to help the Developers Community around the world

Yes, I'd like to help the MrBool and the Developers Community before download

No, I'd like to download without make the donation

Java EE: Working with Asynchronous Design Pattern

See in this article what is the Asynchronous Design Pattern, how it is implemented in pure code (POJO) and how we can implement it in the new Java EE 7 platform using beans and servlets

Although the classic books of design patterns such as GoF book does not cite asynchronous programming as a design pattern, this programming model is one of the most popular and important of the last decade. This asynchronous programming model is based on the idea of a multi-threaded environment and implementation features in separate threads. It can be seen that not only are multithreaded environments and programming languages that take advantage of asynchronous programming techniques, but also the platforms that operate with a single thread, such as the popular JavaScript platforms such as Node.js, which also make use of the principles of asynchronous programming. Furthermore, the GUI frameworks with user (UI - user interface) also use very asynchronous calls mainly to keep the active and responsive interfaces.

Java is designed to support multiple threads from the beginning of its development. However, Java has failed to provide a unique way to make asynchronous calls. Future interface introduced in Java 5 was the first attempt to implement asynchronous programming, but it was heavy and awkward to use. In upcoming versions of Java it was included @Asynchronous note that greatly facilitated the implementation of asynchronous calls. Servlets also provided a better set of tools to help in asynchronous programming.

Asynchronous programming can also be useful on the server side (or back-end). At first, J2SE and J2EE platforms did not offer a simple implementation for asynchronous programming. However, in the Java 5 Concurrency framework was launched based on the JSR166 specification. The JSR166 included several utilities that made possible asynchronous programming, making it easier and better controlled. In addition, Future interface also provided a way to help developers implement an asynchronous execution. However, Spring offered call asynchronous methods that were available with notes. In turn, the Java EE platform has not included until then no convenient solution to the release of version 6.

The rest of the article we will see how to implement the standard as a POJO (Plain Old Java Objects). It will also be seen as the standard Asynchronous can be implemented in the Java EE platform.

Asynchronous pattern

Asynchronous programming is not specified in the main bibliographies design patterns, however, if it would be best described as: "The asynchronous design pattern provides a way to invoke a method without blocking the caller."

The natural form of the execution of a method is the caller blocks until the method called finalize its implementation. Although this behavior is simple and hoped he can not your desired behavior in some cases. Virtually all GUI frameworks with the user and web platforms work with no blocking of requests.

The default asynchronous approach is based on the "fire and forget" in which an operation is performed in parallel or in order not to block the thread executor, and the result is checked when it is ready. Usually asynchronous approach makes use of parallel execution.

The rest of the article shows the practical operation of the asynchronous pattern.

Implementing an Asynchronous in Pure Code (POJO)

Java supports the use of threads in a very simple way as shown in the example in Listing 1.

Listing 1. Example of using Threads with Java

  public class ExampleAsyncRunnable implements Runnable {
   public void run() {
    System.out.println("Running Async Thread!");
   }
  }

To run the code because we must start it on a thread and invoke the method "run()" calling the "start()" of the new thread created, as shown in the following example:

(new Thread(new ExampleAsyncRunnable())).start();

Although many developers use this approach shown above, there is another way to start a process on a separate thread. Simply extend the Thread class and overriding the "run()" as shown in the example in Listing 2.

Listing 2. Example of another approach to creating threads through the extension of the Thread class

 public class ExampleAsyncThread extends Thread {
  public void run() {
   System.out.println("Running Async Thread!");
  }
 }

To run the class simply instantiate it and then call the method "start()", as shown in the following code:

 (new ExampleAsyncThread()).start();

When working with Threads two operations are widely used, they are: the operation "sleep()" and the operation "join()". Both operations throw an InterruptedException exception.

The method "sleep()" causes the thread to be inactive for a specified period which is given in milliseconds. The following example places a thread in the "sleep" or paused for a second:

Thread.sleep(1000);

On the other hand, the method "join()" causes a thread wait for the completion of the execution of another thread. As an example can be considered a thread named t1 that needs a another thread feature called t2. To implement t1 so that the wait for the finalization of t2 must call join in t1 to t2 as shown in the following example:

t2.join();

One of the most known approaches and more used for Java asynchronous programming is using the Future interface. This interface enables the use of the proxy object, which provides a reference for the Future object. Due to the Concurrency framework does not support annotations for asynchronous execution, the Future interface is coupled to a ExecutorService, which is part of Concurrency framework.

The example in Listing 3 uses an executor service to complete a task as it returns a reference to the Future interface with their appropriate generic types.

Listing 3. Example of use of the Future interface and ExecutorService

ExecutorService executor = Executors.newSingleThreadExecutor();
Future <String> testeFuture = executor.submit(new Callable<String> () {
 public String call() {
  return "Running Test!!";
 }
}); 

//.. if (testeFuture.isDone()) System.out.println(testeFuture.get());

System.out.println(testeFuture.get());

The FutureTask class is an implementation of Future interface, which implements the Runnable interface and can be run directly, as shown in the example in Listing 4.

Listing 4. Example of using FutureTask

FutureTask<String> futureTask = new FutureTask<String> (new Callable<String> () {
 public String call() {
  return "Running Test!!";
 }
});

executor.execute(futureTask);

This execution can be canceled through a call to the "cancel" which has the following signature:

cancel (boolean mayInterruptIfRunning) 

If the parameter "mayInterruptIfRunning" is set to true, the method calls for "SessionContext.wasCancelled()" return true. Otherwise, the call to the "SessionContext.wasCancelled()" returns false. Another feature that can be used to check the cancellation status using the "isCancelled()" which returns true if the cancellation was successful.

The Concurrency framework specified in JSR-133 is a great tool for threads and competition, as well as the Fork/Join in Java 7.

In the next section we will be seen how to implement asynchronous pattern in Java EE platform.

Implementing Asynchronous the Java EE platform

The first way to implement asynchronous pattern in Java EE platform is via Asynchronous Beans. The Java EE supports asynchronous programming in several ways, the simplest is through notes. Simply annotate a method with @Asynchronous note. This is enough for the Java EE container run method called in a separate thread. Here in Listing 5 is an example of an asynchronous bean.

Listing 5. Example of a Bean Asynchronous

 package com.mrbool.asyncexample;
   
import javax.annotation.PostConstruct;
import javax.ejb.Singleton;
import javax.ejb.Startup;
import java.util.logging.Logger;
import javax.ejb.Asynchronous;

@Startup
@Singleton
public class ExampleMeuBeanAsync {
	   private Logger logger;

	   @PostConstruct
	   public void start() {
			 // logger initialization
			 logger = Logger.getLogger("ExampleLogGlobal");
			 logger.info("First logged message!!!");
	   }

	   public void logInfoSincrono(String msg){
			 logger.info(msg);
	   }

	   @Asynchronous
	   public void logInfoAssincronamente(String msg){
			 logger.info(msg);
	   }
}

In the example, "logInfoAssincronamente()" method is executed asynchronously, different from the "logInfoSincrono()" method.

To be noted the asynchronous behavior simply add a call to "Thread.sleep()" in the two methods as shown in the example in Listing 6.

Listing 6. Example of the previous methods modified to display the asynchronous behavior

 public void logInfoSincrono(String msg) {
  logger.info(“Getting sync log”);

  try {
   Thread.sleep(1000);
  } catch (InterruptedException e) {}

  logger.info(msg);
 }

 @Asynchronous
 public void logInfoAsync(String msg) {
  logger.info(“Getting async log”);

  try {
   Thread.sleep(13000);
  } catch (InterruptedException e) {}

  logger.info(msg);
 }

It may also be using a "System.out.println()" to the examples shown if the information you want to be displayed on the console.

Finally, you must create a new bean to call both functions in order, as shown in the example in Listing 7.

Listing 7. Example of how to test the above methods and their proper behavior

 package com.mrbool.asyncexample;
   
  import javax.annotation.PostConstruct;
  import javax.ejb.Singleton;
  import javax.ejb.Startup;
   
  @Startup
  @Singleton
  public class TestaBeanAsync {
   
           @EJB
           ExampleMeuBeanAsync beanAsync;
           @PostConstruct
           public void testaLoggers() {
                     System.out.println("Calling async method...");
                     beanAsync.logInfoAsync("Async method executed.");
                     System.out.println("Calling sync method...");
                     beanAsync.logInfoSincrono("Sync method executed.");
                     System.out.println("Done");
           }
  }

Thus, the output will be in order first the message "Calling asynchronous method ...", "Entering the asynchronous log", "Calling synchronous method ...", "Entering the synchronous log", "Synchronous method executed", " finished "and finally" asynchronous method runs. "

Thus, it has to be after running the "testaLoggers()" methods are called "logInfoAsync()" method and "logInfoSincrono()". Both methods pause the execution of threads for a given time. As can be seen from the console output, asynchronous method "logInfoAsync()" was called and entered a long waiting time is 13000 milliseconds, but it does not block the execution of the method "logInfoSincrono()". The method "logInfoSincrono()" sleep for a while, but returns control to the calling method and prints the "Finished" message. Finally, the method "logInfoAsync()" wakes up and ends printing on the console.

This example clearly shows that the asynchronous call does not block the calling thread, also does not block the method "logInfoSincrono()" as shown in the example. However, when the method "logInfoSincrono()" goes to the sleep state, the calling method waits until this pause is over, it is because it is not an asynchronous method that is running on another thread of execution. The @Asynchronous annotation is an easy way to implement asynchronous behavior and can be added to almost any method at any time during and after the development.

Another way to implement asynchronous pattern in Java EE platform is using Asynchronous Servlets. You can implement an asynchronous servlet.

The Servlet 3.0 specification detailed in JSR315 contains major improvements and upgrades to support an asynchronous execution model. It also has easier settings to be performed, among other features that have been incorporated.

Servlets asynchronous basically based on improvements in the Hypertext Transfer Protocol (HTTP) 1.1. In HTTP version 1.0 each connection is used to send and receive a single request and response, unlike HTTP 1.1 as it enabled web applications could maintain active connections and send so many requests.

In a standard implementation of the Java backend need a separate thread constantly attached to HTTP connection. However, the Java API nonblocking I/O or NIO recycles threads between active requests.

Currently all web servers compliant with the Servlet 3.0 specification support the Java NIO.

The Servlet 3.0 introduced the method "startAsync()" that allows asynchronous operations as shown in the example in Listing 8.

Listing 8. Example using startAsync() method

 package com.mrbool.asyncexample;
   
  import java.io.*;
  import javax.servlet.*;
  import javax.servlet.annotation.*;
  import javax.servlet.http.*;
   
  @WebServlet(urlPatterns={"/async"}, asyncSupported=true)
  public class ExampleServletAsync extends HttpServlet {
   
           @Override
           protected void doGet(HttpServletRequest req, HttpServletResponse res)
                     throws IOException, ServletException {
   
                     final AsyncContext asyncContext = req.startAsync();
                     final String information;
   
                     asyncContext.addListener(new AsyncListener() {
                              @Override
                              public void onComplete(AsyncEvent event) throws IOException {
                                        AsyncContext asyncContext = event.getAsyncContext();
                                        asyncContext().getWriter().println(information);
                              }
   
                              @Override
                              public void onTimeout(AsyncEvent event) throws IOException {
                                        // Code here if timeout occurs
                              }
   
                              @Override
                              public void onError(AsyncEvent event) throws IOException {
                                        // Code here if an error occurs
                              }
   
                              @Override
                              public void onStartAsync(AsyncEvent event) throws IOException {
                                        // Code here that should be run at startup
                              }
                     });
   
                     new Thread() {
                              @Override
                              public void run() {
                                        asyncContext.complete();
                              }
                     }.start();
   
                     res.getWriter().write("Results:");
   
                     information = "researched information";
           }                  
  }

This Servlet prints "Results" and then prints the information that can be retrieved from a database, but for this example it is a simple string. As can be seen a separate thread should be started. The method "onComplete" Listener AsyncListener runs only when the execution is complete. There are several other methods AsyncListener the life cycle are: "onStartAsync" that executes when the asynchronous connection is initiated "onTimeout" running when a timeout occurs and "onError" which runs only if an error is received.

It may be noted that the code shown is not very clear and clean. Thus, the Servlet 3.1 specification provides an even easier way to implement asynchronous servlets which uses managed thread pools and executor service. In Listing 9 is an example using ManagedThreadFactory to create a new thread.

Listing 9. Example using ManagedThreadFactory to create a new thread

 package com.mrbool.asyncexample;
   
  import java.io.*;
  import javax.servlet.*;
  import javax.servlet.annotation.*;
  import javax.servlet.http.*;
   
  @WebServlet(urlPatterns="/async", asyncSupported=true)
  public class ExampleServletAsync extends HttpServlet {
   
           @Resource
           private ManagedThreadFactory factory;
   
           @Override
           protected void doGet(HttpServletRequest req, HttpServletResponse res)
                     throws ServletException, IOException {
   
                     final AsyncContext asyncContext = req.startAsync();
                     final PrintWriter writer = res.getWriter();
   
                     Thread thread = factory.new Thread(new Runnable() {
                              @Override
                              public void run() {
                                        writer.println("Execution complete!");
                                        asyncContext.complete();
                              }
                     });
   
                     thread.start();
           }
  }

ManagedThreadFactory acts like a thread availbale at the pool that needs to be started implicitly.

Another way is submitting directly to the ManagedExecutorService instead of creating and initiating the thread in the servlet according to the example shown in Listing 10.

Listing 10. Example of how to delegate to the ExecutorService

 package com.mrbool.asyncexample;
   
  import java.io.*;
  import javax.servlet.*;
  import javax.servlet.annotation.*;
  import javax.servlet.http.*;
   
  @WebServlet(urlPatterns="/async", asyncSupported=true)
  public class ExampleServletAsync extends HttpServlet {
   
           @Resource
           private ManagedExecutorService executor;
   
           @Override
           protected void doGet(HttpServletRequest req, HttpServletResponse res)
                     throws ServletException, IOException {
   
                     final AsyncContext asyncContext = req.startAsync();
                     final PrintWriter writer = res.getWriter();
   
                     executor.submit(new Runnable() {
   
                              @Override
                              public void run() {
                                        writer.println("Execução completa!");
                                        asyncContext.complete();
                              }
   
                     });
           }
  }

Thus, it can be seen that asynchronous servlets also provide a clean and clear implementation can be used without problems.

Bibliography

[1] Erich Gamma, Ricard Helm, Ralph Johnson, John Vlissides. Design Patterns: Elements of Reusable Object-Oriented Software (Addison-Wesley, 1994).

[2] Eric Freeman, Elisabeth Robson, Bert Bates, Kathy Sierra. Head First Design Patterns. O'Reilly Media, 2004.

[3] Murat Yener, Alex Theedom. Proffesional Java EE Design Patterns. Wrox, 2015.



Fabrí­cio Galdino is a software expert and has worked with IT analysis and business development for more than five years. It has extensive experience with testing, back and front-end technologies.

What did you think of this post?
Services
[Close]
To have full access to this post (or download the associated files) you must have MrBool Credits.

  See the prices for this post in Mr.Bool Credits System below:

Individually – in this case the price for this post is US$ 0,00 (Buy it now)
in this case you will buy only this video by paying the full price with no discount.

Package of 10 credits - in this case the price for this post is US$ 0,00
This subscription is ideal if you want to download few videos. In this plan you will receive a discount of 50% in each video. Subscribe for this package!

Package of 50 credits – in this case the price for this post is US$ 0,00
This subscription is ideal if you want to download several videos. In this plan you will receive a discount of 83% in each video. Subscribe for this package!


> More info about MrBool Credits
[Close]
You must be logged to download.

Click here to login