设计模式:单身人士的困惑

时间:2014-07-21 22:29:24

标签: design-patterns singleton

我一直在做一些主要的设计模式阅读和主题SINGLETONS正在困扰我的HELL。在基本OOP中,我们了解到STATIC变量是CLASS级变量,因此基本上只能有一个实例。

现在,单例的基本实现旨在返回一个STATIC变量,该变量包含自己类的新对象,并且只实例化一次。

class MyClass {
      public static MyClass initVar;

      private MyClass (){}

      public static getInstance (){
           if(initVar == null){
              initVar = new MyClass();
           }
           return initVar;
      }

}

在用于使用JVM解释此示例的示例中,据说在多线程系统中,如果 getInstance 变量未成为线程,则可以初始化此类的多个实例在方法名称之前使用 synchronize 指令是安全的,所以这就是我的困惑和我的问题。

示例......

var MyClass a = MyClass.getInstance(); //non thread-safe

现在从示例中可以看出,这种非线程安全的实现可以导致MyClass变量 intVar 的MULTIPLE实例,这些实例早先声明为STATIC。我们怎样才能让ONE CLASS返回多个STATIC变量?

即使调用创建多个MyClass对象,也不应该 intVar 仍然只是简单地指向在其上创建的最新MyClass对象,因此我们仍然应该有一个CLASS INSTANCE,最后一个创建了哪个 intVar 现在指向?

对于每个非线程安全的调用,我们实际上可以有多个STATIC变量吗? MyClass.getInstance()

这怎么可能?

2 个答案:

答案 0 :(得分:1)

以下是单身人士应该如何实施的方式:

class MyClass {
      public static final MyClass initVar = new MyClass();

      private MyClass (){}

      public static MyClass getInstance (){
           return initVar;
      }
}

完全线程安全。

您不会在Singleton中包含有关可变状态的任何信息。如果您添加任何内容,则必须进行同步。

在你所有的研究之后,你会发现,如果今天写了GoF书,那么Singleton将会被选出岛外。 Google进入great deal of trouble以取消Singletons。

答案 1 :(得分:1)

多线程访问单例的问题是所谓的“竞争条件”问题不在于它会返回不同的实例。问题是当多个线程试图同时访问相同的数据时。您需要同步保护数据,因此在给定时间只有一个线程访问您的单例。

我用于单身的一种技术是使用'懒惰实例化':

class MyClass{
public static final MyClass initVar = 0;

public static MyClass getInstance(){
     if (self.initVar == 0){
         // -> Lazy instantiation, this should only happen once. 
         // You can add some assert code here to verify that this is only 
         // happening once in your application. With lazy instantiation you 
         // wait until you actually need the object to create it.
         self.initVar = new MyClass();   
     }

     return initVar;
    }

}