« Paper: Architecture of a Highly Scalable NIO-Based Server | Main | Product: Wackamole »
Sunday
Oct072007

Using ThreadLocal to pass context information around in web applications

Hi,

In java web servers, each http request is handled by a thread in thread pool. So for a Servlet handling the request, a thread is assigned. It is tempting (and very convinient) to keep context information in the threadlocal variable. I recently had a requirement where we need to assign logged in user id and timestamp to request sent to web services. Because we already had the code in place, it was extremely difficult to change the method signatures to pass user id everywhere. The solution I thought is
class ReferenceIdGenerator {
public static setReferenceId(String login) {
threadLocal.set(login + System.currentMillis());
}

public static String getReferenceId() {
return threadLocal.get();
}
private static ThreadLocal threadLocal =
new ThreadLocal();


}

class MySevlet {
void service(.....) {
HttpSession session = request.getSession(false);
String userId = session.get("userId");

ReferenceIdGenerator.setRefernceId(userId);
try {
doSomething();
}
finally {
ReferenceIdGenerator.remove();
}
}

This method is also discussed at
http://crazybob.org/2006/07/hard-core-java-threadlocal.html

Is this a reasonable approach to pass context information in web application?
Can this ever happen that while a http request is being processed in the thread, a thread is suddenly assigned to some other tasks? I hope this can never happen, because app servers themselves rely heavily on threadlocals to keep transaction related information around.
What do you think?

Thanks,
Unmesh

Reader Comments (3)

You've pointed out what can go so wrong with threadlocal: it becomes horrible unmanageable garbage pit of every left over thing. Nobody knows who is using it or how it's being used. Some possible problems:

* Task variables increase the context switch time so you want to minimize them.
* Any 3rd party code can insert threadlocals so you can get strange unexpected errors. Maybe they use the same keys as you, or corrupt your data, leak memory, etc. Especially when tasks are reused in a pool.
* Easy to leak memory.
* I remember reading that classloaders couldn't be undeployed because of some threadlocal conflicts.

IMHO threadlocal should be saved for generic thread features like thread specific memory allocation and performance monitoring. Have a request object where you can store all the context you need to process work. At least that way everyone knows what's going on by looking at the code. That being said, it is very convenient :-)

December 31, 1999 | Unregistered CommenterTodd Hoff

Is this a pattern to use ThreadLocal for storing "Request Execution Context" in web applications? (Like we have "ThreadLocal session pattern" in Hibernate)?

December 31, 1999 | Unregistered Commenterunmesh

ThreadLocal can cause some trivial error when the client calls the service with a fixed thread pool size. ThreadLocal variables are retained until the thread is alive. In this case of ThreadPool, the threads are alive even for multiple calls causing the perm gen overloaded with each request resulting in new thread-local variables each time which may result in OOM.

The better option here would be to clear the thread-local variable once the request is going out of the web service.

September 24, 2018 | Unregistered CommenterAmit Jayee

PostPost a New Comment

Enter your information below to add a new comment.
Author Email (optional):
Author URL (optional):
Post:
 
Some HTML allowed: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <code> <em> <i> <strike> <strong>