`

Threadlocals and memory leaks in J2EE

 
阅读更多
Threadlocals are used in J2EE application servers to keep track of transaction context and security context. I was thinking of using it to pass execution context (which involves some user login and other context information) around in web application which involves servlets and other server side classes. (As discussed at http://www.theserverside.com/news/thread.tss?thread_id=41473).
I remember reading somewhere that Threadlocals can cause memory leaks if Threads are getting reused through thread pools. (Which is the case in J2EE application servers).
What way can Threadlocal cause memory leak? How Threadlocals behave with Classloaderes in J2EE? In what cases thread local usage is not recommended?

Thanks,
Unmesh

Joshua Bloch 回复
Folks,

This thread is littered with misinformation.  Java's ThreadLocal implementation is very, very fast.  It has been completely re-written several times, getting faster each time.  (Props to Doug Lea.) Larry Riedel's description ("some Java code that does a lookup in a hashtable where the Thread object is a key, which is something I as an application developer could do myself.") is wrong on two counts: Only the 1.2 implementation, which was a stopgap, was implemented as per-ThreadLocal map from thread to value.  And practically all application programmers could not "do it themselves." I suggested adding thread locals to the platform only after I saw the fourth broken implementation out of four independent attempts.  Without naming names, these implementations were written by elite systems programmers.

There is nothing inherently wrong with thread locals: They do not cause memory leaks. They are not slow. They are more local than their non-thread-local counterparts (i.e., they have better information hiding properties).  They can be misused, of course, but so can most other programming tools.

Whether thread locals are in the language or the libraries is largely a matter of syntax.  In '97 I proposed adding thread locals to the language (the threadlocal modifier), but there was insufficient support for this, so I wrote the ThreadLocal API that we now use.

Larry says "It is not apparent to me there are many situations for ordinary application programmers where using ThreadLocal would be a better idea than just using some sort of application level mapping."  I am flabbergasted.  What makes Larry think that Joe Programmer's ThreadLocal implementation will be better than the one that Doug and I wrote and carefully optimized? It most certainly will not.

There are many compelling uses for thread locals.  Here are a few off the top of my head:

(1) Genuine per-thread context, such as user id or transaction id.  Works great.  Easy to clean up when the thread exits the scope.  No leaks.

(2) Per-thread instances for performance.  Aaron's SimpleDateFormat example (above) is one example of this pattern.

(3) "Sleazing" values through callbacks that you don't control: sometimes you must call a library method that calls back into your package.  At this point, you need some context that you were unable to pass to yourself, due to deficiencies in the library.  In this rare situation, thread locals can be a lifesaver.

In all of these cases, thread locals are the right thing to use.  Can you cause unintended object retention with thread locals?  Sure you can.   But you can do this with arrays too. That doesn't mean that thread locals (or arrays) are bad things.  Merely that you have to use them with some care.  The use of thread pools demands extreme care.  Sloppy use of thread pools in combination with sloppy use of thread locals can cause unintended object retention, as has been noted in many places.  But placing the blame on thread locals is unwarranted.  Virtually all threading systems of which I'm aware provide support for thread local variables.  There's a reason for this: they are a fundamental part of the thread abstraction.

           Uappologetically yours,

           Josh
分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics