[英]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.