tomcat|Tomcat 线程池和ThreadLocal的爱恨情仇

这两个对象大家应该都不陌生,一个tomcat响应http请求的线程池,在xml配置文件中可以配置大小,另一个为了保证线程安全用来存储变量的threadlocal对象。这两个如果在使用时配合不好,会给程序引入很大麻烦,并且带来难以fix的bug.
下面以一个工作中的案例为大家讲解,通过报错的日志文件发现创建线程时,提示hashmap转成hashtable失败。
经过查看代码发现一行如下代码
threadlocal a = new threadlocalmap(), 这个threadlocalmap是来自log4j中的一个辅助类继承自threadlocal对象,经过分析发现这个threadlocalmap重写了childvalue方法,立马写到输入参数强转为hashtable,但是这个变量定义的泛型明显是hashmap。因为在程序启动后并无影响,但是在 a 这对象被set值以后如果再次创建线程对象并且在查找childvalue时,就会发生异常。
【tomcat|Tomcat 线程池和ThreadLocal的爱恨情仇】另外定义的threadlocal对象会一直绑定到tomcat请求的线程里,并且被缓存到线程池内,下次请求再来时如果分配到这个线程上,就会获取到这个绑定的线程对象,你会发现获取到莫名其妙的值。因此,使用threadlocal是为了保证线程安全,在请求线程结束时应该及时清理里面的值。

    推荐阅读