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.