Spring中的单例bean的线程安全问题

面试题每日一题 专栏收录该内容
14 篇文章 0 订阅

Spring中的单例bean的线程安全问题

因为成员变量是存放在堆内存中,而堆内存又是线程共享的,这就造成了线程安全问题

因为Spring中的Bean默认是单例的,所以在定义成员变量时也有可能会发生线程安全问题

单例的bean 多线程共享,存在资源竞争。如果单例bean 只关注于方法,不会对Bean的成员执行查询以外的操作,这个bean是线程安全的。 重点在于有无对bean 属性的查询以外操作。

Spring容器中的Bean是否线程安全,容器本身并没有提供Bean的线程安全策略,因此可以说Spring容器中的Bean本身不具备线程安全的特性,但是具体还是要结合具体scope的Bean去研究。

Spring 的 bean 作用域(scope)类型

类别说明
singleton在Spring ioc 容器中仅存在一个Bean实例,Bean以单例方式存在,默认值
prototype每次从容器中调用Bean时,都会返回一个新的实例,即每次调用getBean()时,相当于执行new XXxBean()
request每次HTTP请求都会创建一个新的Bean,该作用域仅适用于WebApplicationContext环境
session同一个HTTP Session共享一个Bean,不同Session使用不同的Bean,仅适用于WebApplicationContext环境
global-session一般用于Portlet应用环境,该作用域仅适用于WebApplicationContext环境,全局会话,所有会话共享一个实例。

线程安全这个问题,要从单例与原型Bean分别进行说明。

原型Bean
对于原型Bean,每次创建一个新对象,也就是线程之间并不存在Bean共享,自然是不会有线程安全的问题。

单例Bean
对于单例Bean,所有线程都共享一个单例实例Bean,因此是存在资源的竞争。

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

对于有状态的bean,Spring官方提供的bean,一般提供了通过ThreadLocal去解决线程安全的方法,比如RequestContextHolder、TransactionSynchronizationManager、LocaleContextHolder等。
注: Spring容器本身并没有提供线程安全的策略,因此是否线程安全完全取决于Bean本身的特性。

使用ThreadLocal的好处
使得多线程场景下,多个线程对这个单例Bean的成员变量并不存在资源的竞争,因为ThreadLocal为每个线程保存线程私有的数据。

  • 0
    点赞
  • 0
    评论
  • 0
    收藏
  • 打赏
    打赏
  • 扫一扫,分享海报

©️2022 CSDN 皮肤主题:深蓝海洋 设计师:CSDN官方博客 返回首页

打赏作者

敲一个代码掉一根头发

你的鼓励将是我创作的最大动力

¥2 ¥4 ¥6 ¥10 ¥20
输入1-500的整数
余额支付 (余额:-- )
扫码支付
扫码支付:¥2
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、C币套餐、付费专栏及课程。

余额充值