简体   繁体   English

ThreadLocal类的用途和用途?

[英]Purpose and Use of ThreadLocal class?

I was going through the ThreadLocal class documentation and wondered in what scenarios it can be used. 我浏览了ThreadLocal类文档,想知道可以在哪种情况下使用它。

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. 然后,我查看了ThreadLocal的其他示例,发现ThreadLocal不会帮上忙,因为在大多数情况下,我们有一个在所有线程之间共享的对象。 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. 有了进一步的了解,现在我可以考虑在每个场景需要一个单独对象的情况下使用ThreadLocal类,并且如果特定线程与ThreadLocal中的对象进行交互,则每次都使用同一对象而不是创建一个新对象。

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. ThreadLocal最常用于在应用程序服务器或servlet容器中实现每个请求的全局变量,其中每个用户/客户端请求由单独的线程处理。

For example, Spring, Spring Security and JSF each have the concept of a "Context" through which functionality of the framework is accessed. 例如,Spring,Spring Security和JSF各自具有“上下文”的概念,可通过该上下文访问框架的功能。 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. 在每种情况下,该上下文都是通过依赖项注入(干净的方式) 以及在无法使用或不会使用DI的情况下作为ThreadLocal来实现的。

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). 他们必须使用反射来删除请求之间的所有ThreadLocal实例,以避免一个请求中的数据出现在另一个请求中(这可能会导致讨厌的安全问题)。 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. 例如: SimpleDateFormat不是线程安全的-没有Format是。 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
    }
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM