Spring中的bean是线程的安全的吗?

在学习设计模式的单例模式时,联想到了spring中的单例,比较一下他们的区别:

设计模式单例:在整个应用中只有一个实例
spring单例:在一个ioc容器中只有一个实例
spring中bean的线程安全吗?

在spring框架中,并没有提供bean的线程安全策略,所以,spring中的bean并不具备线程安全特性。

Spring Bean的作用域

singleton:单例bean,每个容器中只有一个bean的实例,Spring中的bean默认是单例的。
prototype:每次请求都会创建一个新的bean实例
request:每一次HTTP请求都会创建一个新的bean实例,该bean仅在当前HTTP request内有效,在请求完成后,bean会失效并被垃圾回收器回收。
session:每一次HTTP请求都会创建一个新的bean,该bean仅在当前HTTP session内有效。同一个session会话共享一个实例,不同的会话使用不同的实例。
global-session:全局session作用域,所有会话共享一个实例。如果想要声明让所有会话共享实例的话,那么这个全局变量需要存在global-session中,而平时中,我们常见的作用域就是singleton和prototype。
prototype(多例bean):对于多例bean来说,因为每次getBean都会创建一个新的对象,线程之间不存在bean的共享问题,所以spring中

的多例bean不存在线程安全问题。

singleton(单例bean):对于单例bean来说,所有的线程都是共享一个单例bean,因此存在线程安全问题,但是如果这个单例bean是一

个无状态的bean,即多线程操作中不会对bean的成员变量进行查询以外的操作(不存在多个线程同时写这个成员变量的场景),那么这个

单例bean就是线程安全的。

有状态的bean:就是有成员变量的对象,可以保存数据,是非线程安全的。
无状态的bean:就是没有成员变量的对象,不能保存数据,是线程安全的。
解决方法:

最简单的解决方案就是将有状态的bean的作用域改为多例的。
在类中定义一个ThreadLocal的成员变量,将需要可变的成员变量保存在ThreadLocal中,采用ThreadLocal解决线程安全问题,这也是比较推荐的。
实际开发中,大多数时候客户端都在访问我们应用中的业务对象,为了减少并发控制,不应该在业务对象中设置那些容易造成出错的成员变量。

文章转自:Spring中的bean是线程的安全的吗?_Java-答学网

作者:答学网,转载请注明原文链接:http://www.dxzl8.com/

你可能感兴趣的