美文网首页Spring
Spring中的Bean是线程安全的吗?为什么?

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

作者: 沈先生的影子 | 来源:发表于2020-10-20 02:22 被阅读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:

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

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

    相关文章

      网友评论

        本文标题:Spring中的Bean是线程安全的吗?为什么?

        本文链接:https://www.haomeiwen.com/subject/zmdrmktx.html