The well acclaimed book JCIP says this about ThreadLocal usage :
It is easy to abuse ThreadLocal by treating its thread confinement property as a license to use global variables or as a means of creating “hidden” method arguments.
Thread-local variables can detract from reusability and introduce hidden couplings among classes, and should therefore be used with care.
What does it mean by saying that Thread-local variables can reduce reusability and introduce hidden couplings among classes?
They reduce reusability in much the same way that global variables do: when you method’s computations depend on state which is external to the method, but not passed as parameters (i.e. class fields for example), your method is less reusable, because it’s tightly coupled to the state of the object/class in which it resides (or worse, on a different class entirely).
Edit: Ok, here’s an example to make it more clear. I’ve used
ThreadLocaljust for the sake of the question, but it applies to global variables in general. Assume I want to calculate the sum of the first N integers in parallel on several threads. We know that the best way to do it is to calculate local sums for each thread and them sum them up at the end. For some reason we decide that thecallmethod of eachTaskwill use aThreadLocal sumvariable which is defined in a different class as a global (static) variable:The code works correctly and gives us the expected value of the global sum, but we notice that the class
Taskand itscallmethod are now strictly coupled to theFooclass. If I want to reuse theTaskclass in another project, I must also move theFooclass otherwise the code will not compile.Although this is a simple example complicated on purpose, you can see the perils of “hidden” global variables. It also affects readability, since someone else reading the code will have to also search for the class
Fooand see what the definition ofFoo.localSumis. You should keep your classes as self-contained as possible.