大家都知道spring的bean默认是单例的,那么,意味着这个bean只会实例化一次,之后注入到各个component的都是同一个实例。
这就是所谓的无状态Bean共享。
也就是说,大家拿到的是同一个Bean对象。既然如此,那么当多个线程调用同一个bean的时候,就会存在线程安全问题。
那Spring如何保证不会出现线程不安全的问题呢?
其实,Spring是用了threadlocal来解决了这个问题。
threadlocal 是什么?
ThreadLocal是一个本地线程副本变量工具类。主要用于将私有线程和该线程存放的副本对象做一个映射,各个线程之间的变量互不干扰,在高并发场景下,可以实现无状态的调用,特别适用于各个线程依赖不通的变量值完成操作的场景。
ThreadLocal的机制:
每个Thread线程内部都有一个Map。
Map里面存储线程本地对象(key)和线程的变量副本(value)
但是,Thread内部的Map是由ThreadLocal维护的,由ThreadLocal负责向map获取和设置线程的变量值。
所以对于不同的线程,每次获取副本值时,别的线程并不能获取到当前线程的副本值,形成了副本的隔离,互不干扰。