Introduction
Java EE 6 comes with two ready to use asynchronous technique:
- EJB
- Servlet
EJB
Example
@Stateless
public class OrderBean {
@Asynchronous
public Future<String> processPayment(Order order) throws PaymentException {
...
String status = ...;
return new AsyncResult<String>(status);
}
}
Oracle Java EE 6 Tutorial: Asynchronous Method Invocation
Oracle Java EE 6 Tutorial: Using Alternatives in CDI Applications
Servlet
This asynchronous feature is less documented, but could be used for example a servlet that generates a PDF or some other heavy computing.
Example
package se.magnuskkarlsson.example.servlet;
import java.io.IOException;
import java.util.concurrent.ArrayBlockingQueue;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;
import javax.servlet.AsyncContext;
import javax.servlet.AsyncEvent;
import javax.servlet.AsyncListener;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
@WebServlet(urlPatterns = "/MyAsyncServlet", asyncSupported = true)
public class MyAsyncServlet extends HttpServlet {
private static final long serialVersionUID = 1L;
@Override
protected void doGet(HttpServletRequest request,
HttpServletResponse response) throws ServletException, IOException {
AsyncContext ac = request.startAsync(request, response);
ac.addListener(new AsyncListener() {
@Override
public void onComplete(AsyncEvent event) throws IOException {
event.getSuppliedResponse().getWriter().println("onComplete");
}
@Override
public void onTimeout(AsyncEvent event) throws IOException {
event.getSuppliedResponse().getWriter().println("onTimeout");
event.getAsyncContext().complete();
}
@Override
public void onError(AsyncEvent event) throws IOException {
event.getSuppliedResponse().getWriter().println("onError");
}
@Override
public void onStartAsync(AsyncEvent event) throws IOException {
event.getSuppliedResponse().getWriter().println("onStartAsync");
}
});
ThreadPoolExecutor executor = new ThreadPoolExecutor(2, 4, 10,
TimeUnit.SECONDS, new ArrayBlockingQueue<Runnable>(2));
executor.execute(new MyAsyncService(ac));
}
class MyAsyncService implements Runnable {
AsyncContext ac;
public MyAsyncService(AsyncContext ac) {
this.ac = ac;
}
@Override
public void run() {
try {
ac.getResponse().getWriter()
.println("Running inside MyAsyncService");
} catch (IOException e) {
throw new IllegalStateException(e);
}
ac.complete();
}
}
}