3

在单例设计模式的情况下应该更喜欢什么。

1)make whole getInstance() method synchronized 
OR
2)make only critical section synchronized.

一个人的方法应该是什么,为什么?

4

5 回答 5

5

首先,尝试考虑是否需要惰性实例化。如果没有,则不涉及同步,因为您INSTANCE将在类加载时初始化。

如果您确实需要延迟初始化您的实例,请不要进行getInstance同步,因为这会导致您的所有线程在实例初始化后无缘无故地等待对方。

如果您将在内部使用同步块,则需要仔细检查 null(在同步块的外部和内部)以确保最终只有一个实例;此外,您需要您的实例为volatile.

最佳实践方法是拥有一个私有嵌套类SingletonHolder,在加载时初始化单例实例(但仅在getInstance()调用容器类时加载)。

但是,如果您不需要惰性实例化,最佳实践是使用带有一个常量的枚举。


长话短说,我想你会在这里找到这一切:http ://en.wikipedia.org/wiki/Singleton_pattern

于 2012-08-22T14:40:44.317 回答
3

鉴于单例通常被认为是一种反模式,我会质疑你为什么想要它。

这种模式使单元测试变得更加困难,[6] 因为它将全局状态引入了应用程序。还应该注意的是,这种模式降低了程序中并行性的可能性,因为在多线程上下文中对单例的访问必须是串行的,例如,通过锁定。依赖注入的拥护者会认为这是一种反模式,主要是因为它使用了私有和静态方法

如果可能的话,我会尝试使用依赖注入来解决上述问题。

于 2012-08-22T14:38:02.713 回答
3

我更喜欢使用 an ,enum因为它更简单,并且仍然是线程安全和延迟加载的。

enum Singleton {
    INSTANCE;
}

我不会让它变得比它需要的更复杂。

于 2012-08-22T14:50:18.107 回答
2

Item 3Effective java enforce singleton with property with private constructed or an enum type

于 2012-08-22T14:39:38.937 回答
1

最好的解决方案是根本不使用单例。如果您需要在多线程环境中使用单例,请使整体getInstance同步或立即使用静态字段初始化(对于单元测试来说更糟)。

阅读http://www.ibm.com/developerworks/java/library/j-dcl/index.html

于 2012-08-22T14:39:43.043 回答