一尘不染

Java 什么时候以及如何使用ThreadLocal变量?

java

什么时候应该使用ThreadLocal变量?

如何使用?


阅读 950

收藏
2020-03-03

共2个答案

一尘不染

一种可能的(并且是常见的)用法是,当你有一些不是线程安全的对象,但又希望避免同步对该对象的访问时(我正在看着你,SimpleDateFormat)。而是给每个线程自己的对象实例。

例如:

public class Foo
{
    // SimpleDateFormat is not thread-safe, so give one to each thread
    private static final ThreadLocal<SimpleDateFormat> formatter = new ThreadLocal<SimpleDateFormat>(){
        @Override
        protected SimpleDateFormat initialValue()
        {
            return new SimpleDateFormat("yyyyMMdd HHmm");
        }
    };

    public String formatIt(Date date)
    {
        return formatter.get().format(date);
    }
}
2020-03-03
一尘不染

由于a ThreadLocal是对给定数据的引用,因此在使用线程池的应用程序服务器中使用s Thread时,可能会导致类加载泄漏ThreadLocal。你需要非常小心,以清理ThreadLocal你的所有内容get()set()使用ThreadLocalremove()方法。

如果完成后不清理,则它对作为部署的Webapp的一部分加载的类的任何引用将保留在永久堆中,并且永远不会收集垃圾。重新部署/取消部署Web应用程序不会清除每个Thread对Web应用程序类的引用,因为ThreadWeb应用程序不是你的Web应用程序所拥有的。每次后续部署都将创建该类的新实例,该实例将永远不会被垃圾回收。

由于java.lang.OutOfMemoryError: PermGen space出现一些谷歌搜索之后,你可能最终会遇到内存不足异常,而这只会增加-XX:MaxPermSize而不是修复该错误。

如果你确实遇到了这些问题,则可以使用EclipseMemory Analyzer和/或遵循Frank Kieviet的指南和后续步骤,确定哪个线程和类保留了这些引用。

2020-03-03