2

I was going through the ThreadLocal class documentation and wondered in what scenarios it can be used.

First I thought it can be used in those scenarios where we have third party/legacy classes and we want to handle synchronization issues. Then I looked at other examples of ThreadLocal and found out that ThreadLocal wont help there, because in most of those cases we have single object which is shared across all threads. Is this correct?

With further understanding, now I can think of using the ThreadLocal class in those scenarios where we need a seperate object for each thread and if a specific thread interacts with an object in ThreadLocal, the same object is used every time instead of creating a new one.

Is this correct or am I missing something?

Mat
  • 202,337
  • 40
  • 393
  • 406
M Sach
  • 33,416
  • 76
  • 221
  • 314

2 Answers2

12

ThreadLocal is most commonly used to implement per-request global variables in app servers or servlet containers where each user/client request is handled by a separate thread.

For example, Spring, Spring Security and JSF each have the concept of a "Context" through which functionality of the framework is accessed. And in each case, that context is implemented both via dependency injection (the clean way) and as a ThreadLocal in cases where DI can't or won't be used.

It's bad for maintainability because it hides dependencies, and also directly causes problems because such containers use a thread pool. They have to use reflection to delete all ThreadLocal instances between requests to avoid having data from one request turn up in another (potentially causing nasty security problems). Sometimes it also causes memory leaks.

Basically, it's a feature that can be very useful in a hackish way, but also very dangerous. I'd advise you to avoid it if possible.

Michael Borgwardt
  • 342,105
  • 78
  • 482
  • 720
  • Thanks Michael..As you said ThreadLocal is most commonly used to implement per-request global variables in app servers or servlet container... .Here is my my understanding we normally does not keep global variable in servlet as they will be visible across threads which is dangerous. So threadlocal provides the way to that where variable will be global to each specific thread. Right? – M Sach Oct 02 '11 at 15:55
  • @MichaelBorgwardt can the ThreadLocal be used to hold execution trace? – Gaurav Nov 19 '19 at 13:43
  • 1
    @gaurav: I'm not sure what exactly you mean with "execution trace", but it can hold whatever you want. – Michael Borgwardt Nov 19 '19 at 14:09
0

Another often used application is a per thread cache for objects where synchronization is required but the overhead must be avoided.

For example: SimpleDateFormat is not thread safe - no Format is. Creating always a new instance is not efficient. Synchronizing on one instance in a multithreaded environment is also not efficient. The solution is this:

class Foo
    private final static ThreadLocal<SimpleDateFormat> threadLocal = new ThreadLocal<SimpleDateFormat>(){
        protected SimpleDateFormat initialValue() {
            return new SimpleDateFormat(pattern);
        }
    };
    public void doStuff(){ 
        SimpleDateFormat df = threadLocal.get();
        // use df
    }
}
A.H.
  • 63,967
  • 15
  • 92
  • 126
  • 1
    I wouldn't be certain this really is a better solution performance-wise. Accessing a ThreadLocal is not exactly a simple or cheap operation either. – Michael Borgwardt Oct 02 '11 at 11:56
  • Looking at the source of `ThreadLocal.get()` on one side and stepping through the constructor `SimpleDateFormat(String)` on the other side says something else. Also [this question](http://stackoverflow.com/questions/609826/performance-of-threadlocal-variable) supports my point. – A.H. Oct 02 '11 at 12:05
  • Have you also looked at the source of `ThreadLocalMap`? All I'm saying that it's sufficiently non-trivial that decisions should be based on benchmarks or (better) profiling rather than assumptions. If you have data to support your suggestion, great. – Michael Borgwardt Oct 02 '11 at 12:35
  • First: Have you read the answers in the linked question? There _are_ benchmarks. Second: I think it is very clear, that before caching anything in any way (i.e. not restricted to the ThreadLocal approach) it must be measured if it's really worth the effort or if caching is more expensive. In that sense `ThreadLocal` is just a tool - if it's good for your cases - fine. If not - use a better tool. Third: at the time I saw the caching of a `DateFormat` for the first time the benchmarks looked very positive. – A.H. Oct 02 '11 at 12:50