【问题标题】:Spring Bean creation by factory methods and Breach of Singleton PatternSpring Bean 通过工厂方法创建和违反单例模式
【发布时间】:2013-05-31 09:48:42
【问题描述】:

朋友们,我正在阅读 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 方法(现在不是线程安全的)增加两个线程返回不同实例的可能性。

请帮忙

【问题讨论】:

    标签: multithreading spring thread-safety race-condition


    【解决方案1】:

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

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

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

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

    【讨论】:

      猜你喜欢
      • 2014-07-17
      • 2014-09-24
      • 1970-01-01
      • 2019-04-03
      • 1970-01-01
      • 2021-07-30
      • 2016-08-13
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多