确保ThreadLocal变量在线程池使用时,注意重新初始化及清理
java.lang.ThreadLocal作为一种线程封闭技术,来实现线程安全的一种手段,如果使用不当很容易导致OOM、隐式传递参数丢失、信息错乱等隐患。
ThreadLocal新线程不初始化,导致隐式传递参数丢失
一般通用的技术实现,比如链路信息、用户认证后的信息、压测链路标识、多主体标识、动态数据源切换、数据库连接安全管理等,我们选择java.lang.ThreadLocal存储,或者选择间接保存在链路信息中的java.lang.ThreadLocal中存储,都需要注意此类信息在多线程、跨服务、跨消息传递等情况下的丢失。
ThreadLocal不清理,导致OOM
ThreadLocal碰到线程池时,如果不清理,很容易导致OOM。因为线程池中的某些线程的生命周期和应用的生命周期是一样的,在ThreadLocal里一直存放数据,而不清理,很容易导致OOM。
ThreadLocal不初始化不清理,导致信息错乱
ThreadLocal碰到线程池时,因为线程池中的某些线程是重复利用的,不及时清理,也不初始化,很容易将ThreadLocal中存储的旧值拿来使用,导致信息错乱。
建议
在try-finally中及时清理ThreadLocal值,记得要初始化。
小结
无论是在显示的线程池中使用,还是在隐式的线程池中(如spring boot应用tomcat线程池)使用,及跨服务通信时,ThreadLocal变量记得要及时初始化和清理,否则很容易导致OOM、隐式传递参数丢失、信息错乱等隐患。