单身,关键部分

时间:2012-08-22 14:33:00

标签: c# java design-patterns

在Singleton Design Pattern的情况下,应该更喜欢什么。

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

应该是什么方法以及为什么?

5 个答案:

答案 0 :(得分:5)

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

如果你确实需要懒惰地初始化你的实例,那么使getInstance同步,因为这会导致你的所有线程在实例出现后无缘无故地等待对方初始化。

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

最佳实践方法是使用私有嵌套类SingletonHolder在加载时初始化单例实例(但仅在调用容器类的getInstance()时加载)。 / p>

但是,如果您不需要延迟实例化,最佳做法是使用带有一个常量的枚举。


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

答案 1 :(得分:3)

鉴于singleton通常被认为是一种反模式,我会质疑你为什么要这样做。

  

这种模式使单元测试变得更加困难,[6]   将全局状态引入应用程序。还应该指出   这种模式降低了内部并行性的可能性   程序,因为在多线程上下文中访问单例   必须序列化,例如通过锁定。依赖的倡导者   注射会将此视为反模式,主要是由于其使用   私有和静态方法

如果可能,我会尝试使用dependency injection来解决上述问题。

答案 2 :(得分:3)

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

enum Singleton {
    INSTANCE;
}

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

答案 3 :(得分:2)

Item 3 Effective java

阅读enforce singleton with property with private constructed or an enum type

答案 4 :(得分:1)

最好的解决方案是根本不使用单身人士。 如果你需要在多线程envoronment中使用singleton使整个getInstance同步或立即使用静态字段(对于单元测试更糟糕)。

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