ThreadLocal类的目的和用途?

时间:2011-10-02 10:51:31

标签: java

我正在浏览ThreadLocal类文档,并想知道它可以在什么场景下使用。

首先,我认为它可以用于我们有第三方/遗留类并且我们想要处理同步问题的场景。然后我查看了ThreadLocal的其他示例,发现ThreadLocal不会有帮助,因为在大多数情况下,我们有单个对象,它在所有线程中共享。这是对的吗?

通过进一步理解,现在我可以考虑在每个线程需要一个单独对象的情况下使用ThreadLocal类,如果特定线程与ThreadLocal中的对象交互,则每次使用相同的对象而不是创建一个新的。

这是正确的还是我错过了什么?

2 个答案:

答案 0 :(得分:10)

ThreadLocal最常用于在app服务器或servlet容器中实现每请求全局变量,其中每个用户/客户端请求由单独的线程处理。

例如,Spring,Spring Security和JSF都有“Context”的概念,通过它可以访问框架的功能。并且在每种情况下,在不能或不使用DI的情况下,通过依赖注入(干净方式)将该上下文实现为ThreadLocal

这对于可维护性是不利的,因为它隐藏了依赖性,并且还直接导致问题,因为这样的容器使用线程池。他们必须使用反射删除请求之间的所有ThreadLocal实例,以避免一个请求中的数据在另一个请求中出现(可能导致令人讨厌的安全问题)。有时它也会导致内存泄漏。

基本上,它是一种以黑客方式非常有用的功能,但也非常危险。如果可能的话,我建议你尽量避免使用它。

答案 1 :(得分:0)

另一个经常使用的应用程序是每个线程缓存,用于需要同步的对象,但必须避免开销。

例如:SimpleDateFormat不是线程安全的 - 没有Format。始终创建新实例效率不高。在多线程环境中同步一个实例也不高效。解决方案是:

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
    }
}