设计模式:单例混淆

科兹比

我一直在阅读一些主要的设计模式,而主题SINGLETONS正在使我烦恼。在基本的OOP中,我们了解到STATIC变量是CLASS级别的变量,因此基本上只能具有一个实例。

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

class MyClass {
      public static MyClass initVar;

      private MyClass (){}

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

}

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

这个例子...

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

现在从示例中可以看出,这种非线程安全的实现可以导致MyClass变量intVar的多个实例,该实例早于声明的STATIC。我们如何通过一个类返回多个STATIC变量?

即使调用创建了多个MyClass对象,intVar也不应该仅指向创建于其上的最新MyClass对象,因此我们仍应具有ONE CLASS INSTANCE,即intVar现在指向的最后一个实例吗?

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

怎么会这样?

Jose Llausas的占位符图像

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

我用于单例的一种技术是使用“延迟实例化”:

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;
    }

}

本文收集自互联网,转载请注明来源。

如有侵权,请联系[email protected] 删除。

编辑于
0

我来说两句

0条评论
登录后参与评论

相关文章