Spring单例bean是线程安全的吗?

时间:2013-06-27 12:13:02

标签: java spring spring-mvc

我想知道Spring单例bean是否是线程安全的,如果是,那么为什么,如果不是,为什么呢?

因为我是春天的初学者,所以请帮助。

11 个答案:

答案 0 :(得分:25)

没有。这两个概念甚至没有关系。

单身人士关于创造。此设计模式确保只创建一个类的实例。

线程安全是关于执行。引用Wikipedia

  

如果一段代码只是以保证多个线程同时安全执行的方式操作共享数据结构,那么它就是线程安全的。

因此最终线程安全仅取决于代码和代码。这就是为什么Spring bean本身不是线程安全的原因。

答案 1 :(得分:3)

Spring单例bean不是因为Spring实例化它们而不是线程安全的。遗憾。

答案 2 :(得分:3)

Spring只管理单例bean的生命周期并维护对象的单个实例。线程安全与它无关。

  

如果没有那么为什么?

因为单身和线程安全是两个不同的概念。您可以使用synchronized关键字

来获取线程安全性

答案 3 :(得分:2)

我有不同的看法: Spring单例bean只创建一次,任何时候都只能有一个实例。

假设您有一个在非同步方法中修改的实例变量。在多线程环境中,将为所有线程分配相同的类实例,并且2个并发线程可以更新/更改可能导致意外情况的实例变量。 单例bean不提供线程安全性,现在您知道实例变量的使用可能会导致意外结果,您有2个选项可以解决相同问题:

  1. 不要在多线程环境中使用实例变量。 OR
  2. 在修改实例变量的任何地方使用synchronized block / keyword,以避免出现意外结果。

答案 4 :(得分:0)

  

如果没有那么为什么?

因为您可以在单例中引用非线程安全对象。

但是如果你不这样做,并且你使用spring来注入任何实例变量,那么是的,它们是线程安全的。

答案 5 :(得分:0)

Spring不保证线程安全。这将是你的责任。 Spring将创建一个Singleton,但如果它是可变的,那么它可能不是线程安全的。 IT程序员有责任照顾Spring bean类,这样它应该是线程安全的。

答案 6 :(得分:0)

在Spring中,单例bean不会有任何状态(无状态)。 Singleton bean scope确保每个BeanFactory都有单个实例。因此,在多线程环境中,即使使用单例bean范围也不能保证单个实例。

因此,为了解决这个问题,我们需要将bean范围从 singleton 范围更改为 prototype 范围,因为开发人员有责任确保线程安全。

答案 7 :(得分:0)

Singleton Beans是否是线程安全的取决于其作用域为singleton的类的编写方式。每个调用线程将有自己的执行,并且不会干扰另一个线程的执行,除非在单例范围的类中有一些代码被所有调用线程共享(例如,如果一个类具有被其方法和方法访问的全局声明的变量)。修改值会导致并发问题,因此最好将这些变量放在方法级别而不是类级别。

答案 8 :(得分:0)

不,Spring singelton bean不是线程安全的,这是示例

public class Emmloyee {

private int id;

private String name;

public int getId() {
    return id;
}

public void setId(int id) {
    this.id = id;
}

public String getName() {
    return name;
}

public void setName(String name) {
    this.name = name;
}


}

这是applicationContext.xml

  <bean id="emp" class="com.manikant.Emmloyee" p:id="26"  p:name="Manikant Gautam">

这是测试课程

   public class Test {

public static void main(String[] args) {

    ApplicationContext ctx=new ClassPathXmlApplicationContext("com/manikant/config.xml");
    Emmloyee emp=(Emmloyee)ctx.getBean("emp");
    System.out.println("User "+emp.getName() + " is of age "+emp.getId());
    emp.setName("Changed value");

    Emmloyee emp1=(Emmloyee)ctx.getBean("emp");
    System.out.println("User "+emp1.getName() + " is of age "+emp1.getId());


}

}

此处输出

      User Manikant Gautam is of age 26

      User Changed name is of age 26
valueemp.setName("Changed value");进行的

更改也反映了不同的bean emp1

答案 9 :(得分:0)

根据我的观点,单例类的完全线程安全完全取决于您已经设计/编写了单例类。

如果定义了单例类的任何全局变量将不是线程安全的,因为如果多个线程共享单例对象并执行可以更新全局变量的方法,那么它将不是线程安全的。

为了使任何单例类线程安全,建议使该类成为无状态意味着您应避免在单例类中定义全局变量。

答案 10 :(得分:0)

上游使用并行处理调用了我的服务,它使我的应用程序崩溃。当线程 1 正在处理 beanA 时,另一个请求到达并设置了 beanA 的一些参数。当我的 beanA 存储在数据库中时,我确认它完全是一团糟。我使用原型修复了它。

相关问题