java中的Singleton类或实例

时间:2014-12-20 01:13:36

标签: java spring

据我所知,在Spring框架中,bean的默认范围是Singleton。这意味着每个容器只创建一个bean实例。

但我几乎无法理解以下情况。

例如类,让我们说class" SingleTonClass"在spring context.xml中配置为singleton bean, 1)每次有这个类的请求时,它是否使用相同的实例。如果是,那么如果我从另一个班级new SingleTonClass().sum(3,4)拨打new SingleTonClass().sum(5,6)这样的电话,会给我正确的结果,或者有时会出现问题吗?

2)如果所有请求都使用相同的实例,那么幕后如何才能使用所有请求只使用一个实例?如果有100个请求到同一个单例类,每个请求必须等到上一个请求完成?

编辑:

假设我使用的是@Autowired而不是新的运算符

在我的主类中,我正在尝试使用spring配置的bean。假设MyMain被多次调用(可能是也可能不是并发调用),我想在上面的帖子中理解第2点(编辑)

public class MyMain() {

@Autowired
SingleTonClass singleTonClass;

}




   public class SingleTonClass {

    private int a=0;
    private int b=0;

    public int sum(int a ,int b) {

    return a+b;
    }
  }

3 个答案:

答案 0 :(得分:1)

当您执行new SingleTonClass()时,您将始终获得该课程的新副本。要使用Spring实例化功能,您需要让Spring为您进行配置,例如使用@Autowired注释。

就多个请求同时命中单个实例的问题而言,您必须使您的类无状态或线程安全。这是一个无法简单回答的主题,但您可以启动here.

答案 1 :(得分:1)

您需要编写无状态bean(意味着bean中不应该有任何数据存储),以免担心线程安全。或者你需要自己处理线程安全。默认情况下,Spring会创建类的单例非线程安全实例。甚至"原型"范围不是线程安全的。当您将范围定义为原型时,它只是意味着每次在另一个组件中注入时,spring将创建一个新实例,而不是每次执行这些组件时都会创建一个实例。

例如,A类将两个组件注入bean a1和a2。 SpringContext中只有只有两个实例,即使这些组件提供了数百万个请求。

请参阅此question,详细了解您可以遵循的不同设计策略。

顺便说一下,在示例中我没有看到在类级别需要private int a,b声明。实际上它甚至没有被使用,因此这个bean是线程安全的。

答案 2 :(得分:1)

1)如果您依赖Spring来管理bean,并且正如您所说的那样使用默认的单例范围,那么其他bean将使用相同的实例。但是,如果您自己实例化该类(例如使用new),那么每次都会有一个新类的实例。

2)如果你有100个并发请求,那么将有100个线程,所有这些线程都可以同时调用你的类而不会阻塞。也就是说,您可以使线程彼此等待(例如,使用synchronized或任何Lock类)。当然,性能将受到影响,因为您现在有99个线程在等待的情况。你更喜欢这种解决方案的唯一原因是你的bean有一个共享的,可变的状态,这是我建议的。沿着这些方向,您可以从示例中删除实例变量ab。毕竟,因为ab都作为方法参数传递,所以它们都没有被使用:

public class SingleTonClass {

    public int sum(int a ,int b) {
        return a+b;
    }
}