Spring中的单例Bean与线程安全----总结

转自:
https://blog.csdn.net/weixin_43727372/article/details/100324678
https://blog.csdn.net/csj50/article/details/83016508

1、Spring中的Bean是线程安全的吗?

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

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

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

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

  • 有状态就是有数据存储功能。
    有状态对象(Stateful Bean),就是有实例变量的对象,可以保存数据,是非线程安全的。
  • 无状态就是一次操作,不能保存数据。
    无状态对象(Stateless Bean),就是没有实例变量的对象,不能保存数据,是不变类,是线程安全的。

对于有状态的Bean,Spring官方提供的Bean,一般提供了通过ThreadLocal去解决线程安全的方法,比如RequestContextHolder、TransactionSynchronizationManager、LocaleContextHolder等。

2、为什么spring单例模式可以支持多线程并发访问?

  1. spring单例模式指的是在内存中只实例化一个类的对象。确保某个类只有一个实例,而且自行实例化并向整个系统提供这个实例。
  2. 当多个用户同时请求一个接口服务的时候,容器会给每一个请求分配一个线程,这时候多个线程会并发执行该请求所对应的业务逻辑。如果该逻辑涉及到对该单例状态(成员变量)的改变,就会有线程安全的问题。
  3. Spring使用ThreadLocal来解决线程安全问题,每个线程去执行业务代码的时候,都会去内存申请临时变量,这样就不会涉及变量并发访问冲突的问题。
  4. 一般的 Web 应用划分为展现层、服务层和持久层三个层次,在不同的层中编写对应的逻辑,下层通过接口向上层开放功能调用。在一般情况下,从接收请求到返回响应所经过的所有程序调用都同属于一个线程。

3、JVM是如何实现线程的独立内存空间?

  1. 每当启用一个线程时,JVM就为他分配一个Java栈,栈是以帧为单位保存当前线程的运行状态。某个线程正在执行的方法称为当前方法,当前方法使用的栈帧称为当前帧,当前方法所属的类称为当前类,当前类的常量池称为当前常量池。当线程执行一个方法时,它会跟踪当前常量池。
  2. 每当线程调用一个Java方法时,JVM就会在该线程对应的栈中压入一个帧,这个帧自然就成了当前帧。当执行这个方法时,它使用这个帧来存储参数、局部变量、中间运算结果等等。
  3. Java栈上的所有数据都是私有的。任何线程都不能访问另一个线程的栈数据。所以我们不用考虑多线程情况下栈数据访问同步的情况。

4、Spring使用ThreadLocal解决线程安全原理示例

https://blog.csdn.net/qq_20128967/article/details/81019199

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值