朋友们,我正在阅读Spring 3 in Action
它说: - 当我们使用Constructors创建它们时,Spring Containers默认提供Singleton Bean。但是如果我们使用工厂方法,那么它应该以只返回单个bean的方式实现。带标题的页码37
CREATING BEANS THROUGH FACTORY METHODS
因此,作者必须通过遵循代码来保持线程安全。否则,两个并发线程可能会创建两个Spring Bean实例。
package com.springinaction.springidol;
public class Stage {
private Stage() {
}
private static class StageSingletonHolder {
static Stage instance = new Stage();
}
public static Stage getInstance() {
return StageSingletonHolder.instance;
}
}
静态getInstance()方法每次调用时都返回相同的实例。 (对于线程 安全性,getInstance()采用一种称为“按需初始化持有者”的技术来创建单例实例。)
然后它使用XML
<bean id="theStage"
class="com.springinaction.springidol.Stage"
factory-method="getInstance" />
将getInstance声明为工厂方法。
我明白了。但是,出于好奇,我想如果我通过删除这个静态初始化从Class Stage中删除这个线程安全的概念
package com.springinaction.springidol;
public class Stage {
private Stage() {
}
public static Stage getInstance() {
return new Stage();
}
}
然后可以通过两个同时线程来拥有多个Stage类的实例。我知道这只是一种可能性。在这种情况下,当线程1在Spring Container(ApplicationContext)实例上调用getBean(“theStage”)方法时,就有可能。它发现没有这种bean的实例。在线程2接管的同时它也发现没有这种bean的实例。现在两个线程都创建了两个不同的Spring bean,因为工厂方法不是线程安全的。
如果两个线程通过修改的getInstance方法(现在不是线程安全的)返回不同的实例,这种可能性如何增加呢。
请帮助
答案 0 :(得分:0)
如何增加两个线程返回的可能性 通过修改的getInstance方法的不同实例(不是 现在线程安全)
这种情况唯一的情况是bean是否使用延迟加载。否则spring会在启动时创建bean,每当你的线程请求一个Stage实例时,Spring将返回它已经拥有的那个。
我还没读过这本书,但我想作者正在使用StageSingletonHolder 100%确定bean在当前的类加载器中永远不会有另一个实例。然而,单例是java中的一个谎言,因为你可以拥有多个类加载器,因此可以有多个单例。
这篇非常好的文章解释了这一点:http://tech.puredanger.com/2007/07/03/pattern-hate-singleton/