Friday, June 24, 2005
ThreadLocal rocks and don't let 'em tell you different
ThreadLocal and thread pools just don't mix. You may get away with using ThreadLocal on a thread but as soon as you return and give that thread back to the application server then you can't assume:
- You'll get called again on the same thread.
- Even if you do get the same thread, it may have different threadlocal values as it may have been used by other applications.
Besides, it's a huge security risk. Suppose an application stores sensitive information on an object held in ThreadLocal. Another customer might send a request which gets processed on a thread just used by a different customer and then one can see the information for the other customer.
He then continues to chide the open-source community for using it. Now technically, his statements are true. There are caveats you need to understand about threads and ThreadLocal. But I might as well say "don't use threads because you can't assume your code will be safe". We don't throw out an extremely useful tool because it requires knowledge to use it.
Instead, he should have offered the solution that anyone who writes J2EE apps and who has discovered the greatness of ThreadLocal knows...use a servlet filter.
Try this:
public final class MyFilter implements Filter { public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException { String myAttr = request.getSession().getAttribute("myAttr"); MyThreadLocal.set(myAttr); chain.doFilter(request, response); MyThreadLocal.set(null); } }
Of course, you do need to null out the value at the end, as I've done above. Hey, now that I think of it, wouldn't it be nice if the container did this when the thread was returned to the pool? Maybe the security risk is on the side of Websphere! Now if only there was a Websphere developer around.
BTW- For a good article on ThreadLocal, see this one by Brian Goetz. If you want to know why you should use ThreadLocal, just think about all the methods in your application which take a parameter "User user" and how much more elegant your code would be if you got rid of them all.
If AquaLogic helps use realize the goal of transparent, modularized, and business-focused applications, then it will be a good thing.
But IMHO, today's challenges to scalable, interoperable components are less in the containers and the buses than in what we put in and on them.
Unfortunately, appservers can't, since the appserver has no mechanism to discover all the threadlocals attached to a given thread. It can only null out the ones it knows about. Until the Java language provides something like Thread.removeThreadLocalVars(), users are responsible for nulling out their own threadlocals before returning control to the appserver.
But is that a reason to avoid them completely? Might as well say, dont ever use C because you might forget to deallocate memory. That's just plain silly.
<< Home