Spring并发访问的线程安全性问题总结

好像是在去年毕业面试的时候,面试官问了我这个问题,如何保证Spring并发访问的线程安全问题,当时的我也只是对这些有所了解,仅仅知道spring中的controller、serivce、dao默认为单例,只要不在这些单例中使用成员变量就可以了,然后工作至今,我还是对其中原理有些模糊,遂今天总结一下。

为什么spring并发访问可能会有安全性问题?

多线程指的是同一段代码,有多个不同的线程一起执行,这种情况下我们编码的时候就要有意识的去注意多线程可能造成的数据安全问题。

在spring中,默认的controller、service、dao都是单例的,并且是交由spring容器进行统一管理的,这样做的好处一来是减少了实例的创建次数,降低了系统的开销,二来是将spring框架各个层解耦,由spring容器来实例化并且注入对象,降低了系统的复杂度。

当然,spring也可以生成多实例的bean,只需要将scope设置为"prototype"。

但是单例在多线程环境下,是被多个线程共享的,那么这个单例对象的成员变量就是可以被多个线程同时操作的,比如说A线程修改了成员变量,而B线程读取到的却是A线程修改之前的成员变量,这就可能导致数据安全问题。

如何去避免线程安全问题?

线程安全问题在spring中,因为bean创建默认为单例模式,所以可能会因为成员变量的共享而导致安全问题,我们可以尽量不在单例中使用成员变量,这样就规避了多线程安全问题。

或者我们也可以对我们所使用的成员变量进行加锁,限制该变量在同一时间里只有一个线程能够操作。

又或者我们可以将spring中bean创建的模式改成普通的,可以同时存在多个实例的模式,这样也不会造成多线程安全问题,但是这样做了之后系统会增加很多实例的创建与销毁还有垃圾回收机制所造成的系统开销。

我们还可以通过ThreadLocal来实现线程安全。

为什么spring单例模式下不使用成员变量可以规避多线程安全问题?

因为单例的对象中的成员变量是被多个线程共享的变量,所有线程都能对该单例成员变量进行操作,而我们单例中的方法中所传递的变量是局部变量,局部变量的生命周期仅仅存在于方法执行的开始到结束,对于每个线程来说,局部变量都是独有的,互相不可见的。所以只要我们在单例中不定义使用成员变量,这样便不会造成多线程直接数据安全性问题。

 

 

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值