ThreadLocal的作用
1.ThreadLocal可以实现资源对象的线程隔离,每个线程各用各的,避免争用引发的线程安全问题
局部变量可以实现线程私有,但是只局限于在一个方法内
2.ThreadLocal同时实现了线程内的资源共享
ThreadLocal原理
ThreadLocal默认容量是16,扩容因子是2/3,哈希冲突不是用拉链法,而是用开放寻址法:找到离原本占用位置最近的一个空闲位置。
ThreadLocal键和值的回收
ThreadLocal里的键是弱引用,为了垃圾回收时能释放键。值还是强引用不能。
ThreadLocal值的回收的情况:
1.获取key发现null key;因为ThreadLocal get如果没有键会设为null
2.set key时使用启发式扫描,清除临近的null key,启发次数与元素个数,是否发现null key有关
3.remove(推荐),因为static不会被GC回收
对于单例Bean,所有线程都共享一个单例实例Bean,因此是存在资源的竞争。
如果单例Bean,是一个无状态Bean,也就是线程中的操作不会对Bean的成员执行查询以外的操作,那么这个单例Bean是线程安全的。比如Spring mvc 的 Controller、Service、Dao等,这些Bean大多是无状态的,只关注于方法本身。
有状态对象(Stateful Bean) :就是有实例变量的对象,可以保存数据,是非线程安全的。每个用户有自己特有的一个实例,在用户的生存期内,bean保持了用户的信息,即“有状态”;一旦用户灭亡(调用结束或实例结束),bean的生命期也告结束。即每个用户最初都会得到一个初始的bean。
threadlocal,可以用在spring单例bean的有状态下,解决线程安全问题,比如RequestContextHolder、TransactionSynchronizationManager、LocaleContextHolder等。