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?
开发者_JAVA技巧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?
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.
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
}
}
精彩评论