何时以及如何使用 ThreadLocal 变量?
2022-08-31 04:01:01
何时应使用 ThreadLocal
变量?
如何使用?
一种可能的(也是常见的)用途是,当您有一些不是线程安全的对象,但您希望避免同步对该对象的访问时(我正在看您,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);
}
}
文档。
由于 a 是对给定数据的引用,因此在使用线程池的应用程序服务器中使用 s 时,最终可能会出现类加载泄漏。您需要非常小心地清理任何 s 你或使用 的方法。ThreadLocal
Thread
ThreadLocal
ThreadLocal
get()
set()
ThreadLocal
remove()
如果在完成后不进行清理,则它对作为已部署 Web 应用的一部分加载的类的任何引用都将保留在永久堆中,并且永远不会被垃圾回收。重新部署/取消部署 web 应用不会清理对 web 应用类的每个引用,因为 web 应用不是 Web 应用拥有的东西。每个后续部署都将创建该类的一个新实例,该实例永远不会被垃圾回收。Thread
Thread
由于一些谷歌搜索,您最终将遇到内存不足的异常,并且可能会在一些谷歌搜索之后增加而不是修复错误。java.lang.OutOfMemoryError: PermGen space
-XX:MaxPermSize
如果您最终遇到这些问题,您可以使用Eclipse的内存分析器和/或遵循Frank Kieviet的指南和后续操作来确定哪个线程和类保留了这些引用。
更新:重新发现Alex Vasseur的博客文章,帮助我追踪我遇到的一些问题。ThreadLocal