Asynchronous tasks in JSF applications

Wednesday October 17, 2012 ()

This is an example on how to implement concurrency in JSF applications using the Executor framework.

We used, in our example below, java.util.concurrent.ThreadPoolExecutor as a static instance that is created and destroyed from the init and destroy events listened to by javax.servlet.ServletContextListener of our application. ThreadPoolExecutor execute threads from a queue of Runnable or java.util.concurrent.Callable using an unbounded java.util.concurrent.LinkedBlockingQueue that holds the tasks submitted by clients for execution.

Here is the syntax of java.util.concurrent.ThreadPoolExecutor. Please see the Javadoc for more.

public ThreadPoolExecutor(int corePoolSize,
                  int maximumPoolSize,
                  long keepAliveTime,
                  TimeUnit unit,
                  BlockingQueue<Runnable> workQueue)

Our example

import java.util.concurrent.Callable;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Future;
import java.util.concurrent.LinkedBlockingQueue;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;
import javax.servlet.ServletContextEvent;
import javax.servlet.ServletContextListener;

public class UpdateListener implements ServletContextListener {

    private static ExecutorService executor;

    public void contextInitialized(ServletContextEvent cs) {
         cs.getServletContext().log("Executor service started !");

    public void contextDestroyed(ServletContextEvent cs) {


    cs.getServletContext().log("Executor service shutdown !");

    public static synchronized void submitTask(Runnable runnable) {
        if (executor == null) {

    public static synchronized Future<String> submitTask(Callable callable) {
        if (executor == null) {
        return executor.submit(callable);

    static void  createExecutor() {
        executor = new ThreadPoolExecutor(
                new LinkedBlockingQueue<Runnable>());


For our ServletContextListener to listen to init and destroy (line 15 and line 21), our class must be registered in the deployment descriptor (web.xml) of the application.


If you are using EE6, it can also be annotated with WebListener instead of updating your web.xml.

public class TaskExecutorListener implements ServletContextListener {
	// our ServletListener class above

Client code

Using our class takes implementing Runnable or Callable interface. The inlined code fragment that follows should accomplish submiting a task for execution by our Executor from any of your class or beans. Note that our thread pool is independent of any JSF session.

TaskExecutorListener.submitTask (new Runnable () {
    public void run() {
	// the actual job


The example above, does not return any value or status of the task. Using Callable enables client code to return a value from the task. See below.

Future future = TaskExecutorListener.submitTask (new Callable() {
    public String call () {
        String result;
	// the actual task
	return result;


try {
	String status = future.get ();  // blocks
catch (Exception e) {}

For more other options about using the Java Executor framework please see java.util.Concurrent package.

That's it. Good luck.


Comments (Asynchronous tasks in JSF applications )