我有三个问题:
1.Is there a way to clean ThreadLocal's data when the Thread's task is done.
2.How about when the thread is in ThreadPool.
3.How can I know a Thread is reused and given back to the ThreadPool.
答案 0 :(得分:4)
广告1)要“清除”ThreadLocal
的数据,只需致电ThreadLocal#remove()
。
Ad 2)ThreadLocal
如果从线程池中Thread
访问,则行为不同。
广告3)你不能。它高度依赖于您使用的线程池。一些线程池提供了一种挂钩方式,其他线程池则没有。
旁注:如果线程池的Thread
是新创建或重新使用或返回的,那么通常它不应该有任何意义,除非您想扩展现有的线程池。
答案 1 :(得分:2)
从线程池中删除线程局部变量是应用程序容器中广泛应用的。我在这里回答了有关此主题的问题:Why do some webservers complain about memory leaks they create?
摆脱线程局部变量的最简单方法是摆脱持有它们的脚步。清除这些变量的唯一另一种方法是反射性地访问线程的线程本地映射,它基本上代表一个映射,其中线程ID指向值,这是线程本地指针的实现方式。使用线程本地时没有涉及JVM魔法。最后它只是一张可以清除的地图。 (在链接的文章中,我解释了为什么在共享线程时这通常是一个坏主意。)然而,反射访问将比更新线程更昂贵。
但是,您可能只是重新考虑您的设计。 Guava提供了一个可以使用软引用构建的缓存。这样,您可以构建一个适当的缓存,其中您的密钥可以由特定于线程的UUID组成。我不太了解你的申请,在这里给你进一步的建议。但是,使用线程本地几乎总是错误的。
答案 2 :(得分:0)
有没有办法在Thread的任务完成后清理ThreadLocal的数据。
您可以在任务代码中显式设置null。
线程何时在ThreadPool中。
与1相同。
我怎么知道Thread被重用并返回给ThreadPool。
您也可以使用ThreadLocal。但是您不需要区分新的和重用的线程。