Sunday, March 6, 2011

threadlocal variables in a servlet

Are the threadlocals variables global to all the requests made to the servlet that owns the variables?

I am using resin for the server.

Thanks for awnser.

I think I can make my self more clear.

The specific Case:

I want to:

  • initialize a static variable when the request starts the execution.
  • be able to query the value of the variable in the further executions of methods called from the servlet in a thread safety way until the request ends the execution
From stackoverflow
  • I think they are global to all requests made with that specific thread only. Other threads get other copies of the thread-local data. This is the key point of thread-local storage: http://en.wikipedia.org/wiki/Thread-local_storage#Java.

    Unless you check the appropriate option in the servlets config, the servlet container will use your servlet with multiple threads to handle requests in parallel. So effectively you would have separate data for each thread that's up serving clients.

    If your WebApplication isn't distributed (runs on multiple Java Virtual Machines), you can use the ServletContext object to store shared data across requests and threads (be sure to do proper locking then).

    Julie : Indeed. On a previous project, I stored a user's ticket in their session, and created a filter to transfer the ticket from the session to a thread local to make sure that a user's authentication state was always available to the thread processing the request.
  • Threadlocal variables are always defined to be accessed globally, since the point is to transparently pass information around a system that can be accessed anywhere. The value of the variable is bound to the thread on which it is set, so even though the variable is global, it can have different values depending on the thread from which it is accessed.

    A simple example would be to assign a user identity string to a thread in a thread local variable when the request is received in the servlet. Anywhere along the processing chain of that request (assuming it is on the same thread in the same VM), the identity can be retrieved by accessing this global variable. It would also be important to remove this value when the request is processed, since the thread will be put back in a thread pool.

  • Like Adiel says, the proper way to do this is probably to use the request context (i.e. HttpServletRequest), not to create a ThreadLocal. While it's certainly possible to use a ThreadLocal here, you have to be careful to clean up your thread if you do that, since otherwise the next request that gets the thread will see the value associated with the previous request. (When the first request is done with the thread, the thread will go back into the pool and so the next request will see it.) No reason to have to manage that kind of thing when the request context exists for precisely this purpose.

    sehugg : You could also use a servlet filter to manage the ThreadLocal, at least the creation/cleanup would be in one place.
  • Short answer: Yes.
    A bit longer one: This is how Spring does its magic. See RequestContextHolder (via DocJar).

    Caution is needed though - you have to know when to invalidate the ThreadLocal, how to defer to other threads and how (not) to get tangled with a non-threadlocal context.

    Or you could just use Spring...

0 comments:

Post a Comment