Spring中线程安全
-
保证bean是无状态对象,如Service、DAO和Controller这些都是无状态的对象,只是执行某些操作。bean的生命周期:
-
singleton:默认的scope,每个scope为singleton的bean都会被定义为一个单例对象,该对象的生命周期是与Spring IOC容器一致的(但在第一次被注入时才会创建)。
-
prototype:bean被定义为在每次注入时都会创建一个新的对象。
-
request:bean被定义为在每个HTTP请求中创建一个单例对象,也就是说在单个请求中都会复用这一个单例对象。
-
session:bean被定义为在一个session的生命周期内创建一个单例对象。
-
application:bean被定义为在ServletContext的生命周期中复用一个单例对象。
-
websocket:bean被定义为在websocket的生命周期中复用一个单例对象。
-
-
当bean需要有自己变量时,可以用ThreadLocal将变量变为线程私有,避免多线程共用。最后使用完成,需要手动remove释放内存。
ThreadLocal内部含有一个TheadLocalMap类(采用线性探测法实现的HashMap,key为ThreadLocal对象且为WeakReference)
如果Thread Local被置为null之后,TheadLocalMap的Entry的key也为null,只要线程不结束,这些无法访问的value就会形成内存泄漏,因此即使时弱引用的key,如果不手动调用ThreadLocalMap的set、getEntry和remove函数去自动清理,仍然会存在泄露问题。因此每次使用完毕,都需要手动调用ThreadLocal的remove方法清除无用的Entry。
-
当实例变量需要在多线程中共享时,可以采用Synchronized、CAS、lock等线程同步操作实现线程安全。