[concurrency-interest] Threadlocals and memory leaks in J2EE

Joshua Bloch josh at bloch.us
Tue Oct 9 01:40:28 EDT 2007


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.2implementation, 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
-------------- next part --------------
An HTML attachment was scrubbed...
URL: /pipermail/attachments/20071008/22062fcf/attachment.html 


More information about the Concurrency-interest mailing list