1、介绍两个概念
有状态的 bean:对象中有实例变量(成员变
量),可以保存数据,是非线程安全的。
无状态的 bean:对象中没有实例变量(成员变
量),不能保存数据,可以在多线程环境下共享,是线程安全的。
2、spring 的线程安全问题
2.1我们都知道spring 中的 bean 默认都是单例的,ioc 容器中一个类只会存在一个实例对象。这种设计是怎么保证线程安全的?
一般不会出现线程安全问题。在spring 中,绝大部分 bean 都是无状态的,因此即使这些 bean 默认是单例的,也不会出现线程安全问题的。比如
controller、service、dao 这些类,这些类里面通
常不会含有成员变量,因此它们被设计成单例的。如果这些类中定义了实例变量,就线程不安全了,所以尽量避免定义实例变量。
2.2对于 spring 中有状态的 bean,比如
RequestContextHolder, Transaction SynchronizationManager,
LocaleContextHolder,为什么也能够设计成单例的呢?它是怎么保证线程安全的?
对于有状态的 bean, spring 采用 ThreadLocal
进行处理,使它们成为线程安全可以共享的对象。
对于有状态的 bean,也可以使用原型模式
(prototype),每次使用时都会重新生成一个对象,解决了线程不安全的问题。
ps:无状态的Bean 适合使用不变模式,即单例
模式,这样可以共享实例,提高性能。有状态的
Bean,多线程环境下不安全,适合使用
Prototype 原型模式。Prototype:每次对 bean
的请求都会创建一个新的 bean 实例。
----------原文boss