Leveraging ThreadLocal in a J2EE container for information propagation

This one is related to J2EE application development. Often application developers and a lot of architects are skeptical in working with threads in a managed environment. Loads and loads of java applications that run on high end app servers are getting written. And most of them have the application architected in several layers. I will present below an approach which would help propagate various information “clandestinely” within the application. This is not something new and many frameworks like hibernate (for session binding) use these approaches internally…so what is this all about??? Read further…

The J2EE application servers as well all know work with threads internally so when a given request is being processed, it is attached to its own thread of execution. Even if you are application concerns are well split into multiple layers, the same thread will go layer after layer and execute code. This is something that could be leveraged by applications smartly. Assume for instance I have a typical J2EE application that has a front end layer and a business logic/service layer. There could be backend interactions using implementations of the DAO pattern. It many applications, there could be app-wide information that is required to be used across many layers (example – user information). If there is some way to propagate this information to all layers without having to pass it to all methods, then it will make code that much cleaner and individual coders need not worry about many intricacies. This is where the current thread context comes in handy.

Here is the strategy -Get a handle to the currently executing thread and then set the value  in it(user information in our example).  You are done now – this information is available throughout the thread of execution…..lets look at sample code below,
public class ThreadContext {

private static ThreadLocal<ThreadContext> threadCtx = new InheritableThreadLocal<ThreadContext>();

/** Map of objects that can be added into the thread context **/
private final Map<String, Object> ctxMap = new HashMap<String, Object>();

/**
* <p>This method is to  set an object into the thread context</p>
* @param key
* @param value  void
*/
private void putObjInContext(String key,Object value) {
this.ctxMap.put(key, value);
}

/**
* <p>This method is to  get an object from the thread context</p>
* @param key
* @return  Object
*/
private Object getObjFromContext(String key) {
return this.ctxMap.get(key);
}

ThreadContext(){
//I have used a no argument constructor here. But if you want to default initialize
//anything you can use this place
}

public static ThreadContext getThreadContext(){
return threadCtx.get();
}

/**
* <p>Set the context back into the current thread</p>
*/
public static void setThreadContext(ThreadContext ctx){
threadCtx.set(ctx);
}
}

Here is the usage. Wherever the context is needed, this is what you should do..

ThreadContext.getContext().getObjFromContext(key);

Once the current request is processed, all the context related information is purged and the thread if returned to the pool. It is guaranteed that any information you put on the thread will remain synchronized so no one else other than the current user who is being served can access it. Secondly, once the execution is complete and before the thread if handed back into the pool all information is purged so data will not get shared.

This entry was posted in Uncategorized. Bookmark the permalink.

1 Response to Leveraging ThreadLocal in a J2EE container for information propagation

  1. Bharath says:

    I think the “setThreadContext” method should be as below:

    /**
    * Set the context back into the current thread
    */
    public static void setThreadContext(ThreadContext ctx){
    if(ctx!=null){
    threadCtx.set(ctx);
    } else {
    threadCtx.remove();
    }

    }

    This setter has to be called in the finally or at the end of the thread execution. Else the thread will go back to the pool with an old ctx value still trailing and the next job that uses the thread will have a ctx value from the old job.

    Happy coding 🙂
    BCP

Leave a comment