1

朋友们,我正在阅读 Spring 3 in Action

它说:-默认情况下,当我们使用构造函数创建它们时,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 方法(现在不是线程安全的)增加两个线程返回不同实例的可能性。

请帮助

4

1 回答 1

0

如何通过修改的 getInstance 方法增加两个线程返回不同实例的可能性(现在不是线程安全的)

发生这种情况的唯一情况是 bean 使用延迟加载。否则,spring 将在启动时创建 bean,并且每当您的线程请求 Stage 的实例时,Spring 将返回它已经拥有的那个。

我没有读过这本书,但我猜作者正在使用 StageSingletonHolder 来 100% 确定 bean 在当前类加载器中永远不会有另一个实例。然而,单例在 Java 中是一个谎言,因为您可以拥有多个类加载器,因此可以拥有多个单例。

这篇非常好的文章解释了这一点: http: //tech.puredanger.com/2007/07/03/pattern-hate-singleton/

于 2014-03-27T01:56:43.573 回答