java中的单例
我只需要在某处阅读以下代码:
public class SingletonObjectDemo {
private static SingletonObjectDemo singletonObject;
// Note that the constructor is private
private SingletonObjectDemo() {
// Optional Code
}
public static SingletonObjectDemo getSingletonObject() {
if (singletonObject == null) {
singletonObject = new SingletonObjectDemo();
}
return singletonObject;
}
}
我需要知道这部分需要什么:
if (singletonObject == null) {
singletonObject = new SingletonObjectDemo();
}
如果我们不使用这部分代码怎么办?仍然会有一个SingletonObjectDemo
的副本,为什么我们需要这个代码呢?
没有找到相关结果
已邀请:
7 个回复
校勒魏寡
,用于保存单例实例。现在有两种可能的策略 - 1 - 您使用声明急切初始化对象 -
这将导致您的单例对象在加载类时被初始化。这个策略的缺点是,如果你有很多单身人士,他们都会被初始化并占用记忆,即使他们还不需要。 2 - 你做对象的延迟初始化,即在第一次调用
时初始化它 -
...
这样可以节省内存,直到真正需要单例。这种策略的缺点是方法的第一次调用可能会看到稍微差一点的响应时间,因为它必须在返回之前初始化obejct。
瓜唱鬼
语句是延迟初始化技术的实现。 更明确的版本如下:
会发生的事情是,第一次调用
,
将是
,所以
将被初始化为
。在随后的调用中,
将是
,因此
将不再被调用。 因此,
被“懒惰地”初始化。直到它第一次需要它才真正初始化。 也可以看看 维基百科/懒惰初始化 维基百科/初始化按需持有人的习惯用语 关于线程安全 需要说的是,代码片段不是线程安全的。如果有多个线程,那么在某些竞争条件下,可以多次调用
。 一种解决方案是制作
方法。但是,这对所有对ѭ5的调用都有同步开销。然后使用所谓的双重检查锁定习惯来试图解决这个问题,但在Java中,这个习惯用法在J2SE 5.0中实际上不起作用,在新的内存模型中引入了
关键字。 毋庸置疑,单身模式的正确执行并非易事。 也可以看看 developerWorks / Java:双重检查锁定和Singleton模式 - 全面了解这种破解的编程习惯用法 维基百科/双重检查锁定 相关问题 synchronized block vs synchronized方法? 有效的Java第二版 以下是本书对这些主题的看法: 第71项:明智地使用延迟初始化 与大多数优化一样,延迟初始化的最佳建议是“除非你需要,否则不要这样做”。懒惰的初始化是一把双刃剑。它降低了初始化类或创建实例的成本,但代价是增加了访问延迟初始化字段的成本。根据延迟初始化字段最终需要初始化的部分,初始化它们的成本以及访问每个字段的频率,延迟初始化(就像许多“优化”实际上会损害性能)。 在存在多个线程的情况下,延迟初始化很棘手。如果两个或多个线程共享一个延迟初始化的字段,则必须采用某种形式的同步,否则可能导致严重的错误。 在大多数情况下,正常初始化优于延迟初始化。 第3项:使用私有构造函数或
类型强制执行单例属性 截至1.5发布。实施单例的第三种方法。只需使用一个元素创建一个枚举类型。 [...]这种方法在功能上等同于
字段方法,除了它更简洁,提供免费的序列化机制,并提供针对多个实例化的铁定保证,即使面对复杂的序列化或基于反射的攻击。 [...]单元素枚举类型是实现单例的最佳方式。 相关问题 在
单例/ Java实现: 在Java中实现单例模式的有效方法 Java Enum Singleton 比较Java枚举成员:==或equals()? Singleton中的线程安全性 关于单身模式的优点和替代方案: 关于设计模式:何时使用Singleton? 编程中单例的目的 单身人士真是太糟糕了 单身人士:好的设计还是拐杖? 什么是单身人士的替代品 Singleton:如何使用它
磐剩
调用
方法时 这是第一次
为第一个 时间,造成
级 初始化。这个美丽 成语是
方法 没有同步,只执行一个 字段访问,所以延迟初始化 几乎没有增加成本 访问。一个现代的VM将 仅对字段访问进行同步 初始化课程。一旦上课 初始化后,VM将修补 代码使后续访问 字段不涉及任何测试或 同步。 也可以看看 第66项:同步对共享可变数据的访问 - Effective Java 2nd edition 第71项:明智地使用延迟初始化 - 有效的Java第2版 新内存模型是否修复了“双重检查锁定”问题?
素汞读
顺便说一句,回到你的问题,行:
声明一个静态引用,但它不会实际分配一个实例,Java编译器将引用设置为
。
炉挤仙挟
字段是
,然后构造对象的实例并将其存储在那里。后续请求返回相同的对象。 如果你删除这两行代码,你将永远不会真正创建初始实例,所以你总是会返回
。
呈辖玫割善
莽缓逢