Threadlocal的作用就不用多讲了,主要是一个map用于线程间的数据隔离,正常情况下,线程回收,那么这个线程对应的map值也会被回收(是ThreadLocal中被移除并非值本身被移除,如果是对象并且任然被引用,它是不会被回收的)
基于上面的特点,如果在异步线程中使用ThreadLocal来传递值就有一个注意点,如果异步线程每次都是新建的,那么与它对应的threadlocal的值永远都是隔离的,并且在线程出了线程之后,不管这个线程是否被GC回收,就再也无法访问到值。但是有个特殊情况:线程池。
线程池的特点就是线程可重复使用,在满足timeout、线程数量、没有持续的添加任务的时候线程池中的线程会被回收。如果线程不回收并且被重复使用,那么在使用threadlocal的时候就有可能拿到当前线程前一次的值,简单来说就是线程池的线程被重复使用,导致threadlocal的key是重复的,在下次使用的时候就是上次的值。
针对上面的问题,个人推荐的解决方案有两个
1.在每次出线程之前将值remove,这个比较好理解,就是出了作用域就删除
2.阿里有一套Transmittable的缓存线程池,可用threadlocal用于异步线程池的传递,我也是大概了解,没看过它的原理,在使用的时候得走它的包装(使用方式得正确)。
以上为个人理解,有不对的请大佬指出,谢谢!