简而言之 - tomcat使用线程池,因此可以重用线程。有些库使用ThreadLocal
变量,但不清理它们(使用.remove()
),因此实际上它们会将“脏”线程返回到池中。
Tomcat具有在关闭时检测这些内容以及清除线程本地的新功能。但这意味着线程在整个执行过程中都是“脏”的。
我能做的是实现Filter
,并在请求完成后(并将线程返回到池中),使用code from tomcat清除所有ThreadLocal
(该方法称为checkThreadLocalsForLeaks
)。
问题是,值得吗?两位职业选手:
一个骗局:
Field
s)都将被缓存,但仍然存在。另一个选择是将问题报告给不清除其线程本地的库。
答案 0 :(得分:6)
我会经历向图书馆开发人员报告问题的途径,原因有两个:
老实说,我之前从未见过这种类型的错误,我认为这是一个例外,而不是我们应该保护的事情,因为它经常发生。你能分享你看过这种行为的库吗?
作为旁注,我不介意在开发/测试环境中启用该过滤器,并在仍附加ThreadLocal变量时记录严重错误。
答案 1 :(得分:1)
答案 2 :(得分:1)
如果您认为线程的肮脏可能会导致问题,那么这是明智之举。在可能的情况下应避免出现问题。
使用threadlocals可能是库的不良行为,你当然应该向作者报告,但遗憾的是,现在,由你来处理它。
我不会太担心性能。反射中的慢速位是元数据查找;一旦你有了一个Field对象,那么使用它是相当快的,并且随着时间的推移变得更快 - AIUI,它开始通过对JVM进行本机调用来工作,但经过一些使用后,它会为访问生成字节码,然后可以编译成本机代码,优化,内联等,因此它不应该比直接字段访问慢得多。我不认为Tomcat代码会跨请求重用Field对象,所以如果你想利用它,你必须编写自己的清理代码。在任何情况下,性能成本都将远远低于与请求相关联的IO的成本。