仅创建1个实例或单例

时间:2015-03-28 11:31:02

标签: java design-patterns singleton

我使用了一个叫做“城市”的课程。整个游戏中只有一个城市;创建一个实例(如果只有1个或单个实例)是否有益。

该类本身将包含不会都是静态的方法,&我已经读到单身人士自己只包含静态属性和方法。可能是不好的做法还是我错了?

4 个答案:

答案 0 :(得分:0)

我使用单个实例并将其作为方法参数或构造函数依赖项提供给您需要使用它的位置。

通过这种方式,您可以在测试其他类时轻松模拟它。

答案 1 :(得分:0)

单身人士是一种非常常见的模式。

在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)
    ....

}

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

答案 2 :(得分:0)

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

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

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

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

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)
    ....

}

在某个地方,我看到了另一种基于类初始化的实现,只需按需提供" ...

答案 3 :(得分:0)

今天可用的最佳单例机制是

public enum City {

   INSTANCE;

}

然后你引用像这样的实例

City.INSTANCE;

如果您需要更多城市的方法,那么

public enum City {

   INSTANCE;

   private int xLoc;

   public int getX() {
     return xLoc;
   }
}

带有"创作后卫的单个对象"技术是错误的。虽然他们已经修复了JVM,因此竞争条件不会确保生成两个实例(其中一个实例是垃圾回收),但这些示例都没有处理各种其他方法来复制您的实例。

例如,您可以序列化您的实例,然后反序列化它,并且您有两个副本。