繁体   English   中英

仅创建1个实例或一个Singleton

[英]Creating only 1 instance or a Singleton

我使用了一个名为“城市”的类,整个游戏中只会有一个城市。 如果只有1个或一个单例,则创建一个实例将是有益的。

类本身将包含并非全部为静态的方法,并且我已阅读到单例本身仅由静态属性和方法组成,并且可能是不当行为,还是我弄错了?

我将使用一个实例,并在需要使用它的地方将其作为方法参数或构造函数依赖项提供。

这样,您可以在测试其他类时轻松地将其模拟出来。

单例是非常常见的模式。

在Java中,它们是作为无法在外部创建的对象的私有实例生成的。

public class City {

    private static City SINGLETON;

    public static City get() {
        // lazy construction, may be required to synchronize....
        if( SINGLETON == null ) {
             SINGLETON = new City();
        }

        return SINGLETON;
    }

    private City() {
      ... construct city here ....
    }

    // your City instance methods here (non-static)
    ....

}

如果您有一个依赖项注入框架,则可以使用它来为您管理单例实例。

Singleton是一种非常常见的模式,可以帮助您处理整个运行时环境中对象的一个​​实例。 因此,不要担心区分静态和非静态方法...将它们全部设为非静态方法,因为如果仅通过City.getInstance().method()来调用它们,那么您可以确定method() (以及其他任何方法)将仅在同一实例上被调用。

先前的答案是正确的,但是如果您在多线程环境(作为Web应用程序)中并且必须确保仅创建一个实例,则必须以不同的方式实现单例。

实际上,在prevoius代码中,可能有多个并发线程将创建一个新的City实例...稍后创建的线程将使用最后一个实例(因为它会覆盖静态字段中的第一个实例)。

有几种方法可以解决此问题……最常见的是使getInstance()方法synchronized

public static synchronized City getInstance() {

最有效的方法(在高并发环境中)是使用延迟初始化:

public class City {

    private static volatile City instance;

    public static City getInstance() {
        if( instance == null ) {
            synchronized (City.class) {
                if( instance == null ) {
                    instance = new City();
                }
            }
        }
        return instance;
    }

    private City() {
      ... construct city here ....
    }

    // your City instance methods here (non-static)
    ....

}

在某个地方,我看到了另一个基于类的初始化的实现,只是“按需” ...

今天最好的单例机制是

public enum City {

   INSTANCE;

}

然后像这样引用实例

City.INSTANCE;

如果您需要在城市中使用更多方法,则可以

public enum City {

   INSTANCE;

   private int xLoc;

   public int getX() {
     return xLoc;
   }
}

具有“创建防护”技术的单个对象容易出错。 尽管它们具有固定的JVM,所以竞态条件不能确保创建两个实例(其中一个被垃圾回收),但这些示例均未处理其他各种方法来复制您的实例。

例如,您可以序列化您的实例,然后对其进行反序列化,这样您将拥有两个副本。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM