Spring中的Bean是否是线程安全的

Spring本身并没有对Bean做线程安全的处理,所以

1、如果Bean是无状态的,那么Bean是线程安全的

2、如果Bean是有状态的,那么Bean是线程不安全的

这取决于你的bean是否是有状态的;如果单例Bean,是一个无状态Bean,也就是线程中的操作不会对Bean的成员执行查询以外的操作,那么这个单例Bean是线程安全的。比如Spring mvc 的 Controller、Service、Dao等,这些Bean大多是无状态的,只关注于方法本身。

默认情况下Spring的bean都是单例的,所以就一般业务开发中bean都是无状态的(比如DAO层),所以是线程安全的。

但你的bean是有状态的话(比如你要在bean中存储某些数据),就需要将bean的scope改成prototype,让每次请求都相当于重新new一个bean,这样就是线程安全的了。

Spring作用域(scope)的配置区别:

  • 非线程安全:Singleton(默认): Spring容器只存在一个共享的bean实例。对于单例Bean,所有线程都共享一个单例实例Bean,因此是存在资源的竞争。
  • 线程安全:Prototype: 每次对bean的请求都会创建一个新的bean实例。对于原型Bean,每次创建一个新对象,也就是线程之间并不存在Bean共享,自然是不会有线程安全的问题。   

使用实例:

  • DAO层的实现类推荐设置scope="singleton",这些类没有状态,只需用singleton只需维护一个实例,可提高性能。
  • Struts2的action类推荐设置scope="prototype",action显然是有状态的,需要每次创建一个新的实例,保证线程安全。

拓展:

有状态对象(Stateful Bean) :就是有实例变量的对象,可以保存数据,是非线程安全的。每个用户有自己特有的一个实例,在用户的生存期内,bean保持了用户的信息,即“有状态”;一旦用户灭亡(调用结束或实例结束),bean的生命期也告结束。即每个用户最初都会得到一个初始的bean。

无状态对象(Stateless Bean):就是没有实例变量的对象,不能保存数据,是不变类,是线程安全的。bean一旦实例化就被加进会话池中,各个用户都可以共用。即使用户已经消亡,bean 的生命期也不一定结束,它可能依然存在于会话池中,供其他用户调用。由于没有特定的用户,那么也就不能保持某一用户的状态,所以叫无状态bean。但无状态会话bean 并非没有状态,如果它有自己的属性(变量),那么这些变量就会受到所有调用它的用户的影响,这是在实际应用中必须注意的。

posted @   leagueandlegends  阅读(669)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 全程不用写代码,我用AI程序员写了一个飞机大战
· DeepSeek 开源周回顾「GitHub 热点速览」
· 记一次.NET内存居高不下排查解决与启示
· MongoDB 8.0这个新功能碉堡了,比商业数据库还牛
· .NET10 - 预览版1新功能体验(一)
点击右上角即可分享
微信分享提示