Spring

Spring中的Bean是线程安全的吗?为什么?

2020-10-20  本文已影响0人  沈先生的影子

Spring中的Bean是线程安全的吗?为什么?

        答案:不是。

        因为SpringIOC容器本身没有提供Bean的线程安全策略,所以Spring容器中的Bean本身不具备线程安全的特性,现在结合具体的作用域(scope)去研究。

Spring的Bean作用域scope类型(五种):

        a.singleton(单例):默认作用域,SpringIOC中仅存在一个Bean实例,以单例Bean的方式存在。

        b.prototype(原型):每次从容器中getBean()时,都返回一个新的实例。等于执行new Bean()。

        c.request(请求):每次Http请求创建一个新对象。

        d.session(会话):同一个会话共享一个实例,不同会话使用不同实例。

        e.global-session(全局会话):所有会话共享一个实例。

request(请求)、session(会话)、global-session(全局会话):

        **\color{red}{仅仅适用于WebApplicationContext环境下。}**

        $\color{red}{红色字}$

线程安全这个问题,从常用的单例和原型Bean分别说明:

singleton(单例)Bean:

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

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

prototype(原型)Bean:

        每个线程都创建一个新的对象,线程之间不存在Bean的共享,自然不存在线程安全的问题。

Spring中Bean是默认单例的,为什么Controller、Service、和Dao能保证线程安全?

        Spring 中Bean默认是单例模式的,框架并没有对Bean进行多线程的封装处理。       

        Controller、Service和Dao本身并不是线程安全的,Java虚拟机栈是线程私有的,它的生命周期与线程相同,跟随线程结束而结束。

        但是,如果Bean是有状态的,就需要开发人员自己来进行线程安全的保证,最简单的方法就是改变Bean的作用域把“singleton”改为“prototype",这样每次请求Bean都相当于new Bean(),问题解决。

tips:

        有状态就是有存储数据的功能。

        无状态就是不会存储数据。

上一篇下一篇

猜你喜欢

热点阅读