单身模式(Bill Pugh的解决方案)

Rob*_*Fox 29 java singleton design-patterns

我正在阅读有关单例模式的维基,我不确定我是否理解这一点:https://en.wikipedia.org/wiki/Initialization-on-demand_holder_idiom正确部分.

所以要简单一点:为什么Bill Pugh的解决方案比上面的例子更好?

是因为VM在实际使用之前没有加载静态类或类似的东西,所以在转向getInstance()方法之前我们不创建对象?那个方法线程安全只是在初始化对象的程度吗?

pla*_*nes 30

我认为Pugh先生的版本是高度重视的,因为它只在调用getInstance()时执行单例的实例化,即不是在加载类(持有getInstance方法的类)时.如果您的单件结构造成成本高昂,那么这对您来说可能是一个优势.如果你像世界上大多数人一样,他们的单身人士只是为了避免使用静态方法(并且你没有转向依赖注入框架),那么我就不会失去任何睡眠.

正如文章所述,Pugh先生的方法比静态实例变量更懒惰 - 但实际上如果Singleton类被加载,你无论如何都会调用getInstance方法.因此,作为计算机科学的一部分,它很有用,但在现实世界中它的好处值得商榷.

ps我对布洛赫先生在这里的例子并不在意,因为使用枚举就是说我的单身人士IS-A枚举,这对我来说听起来不对(尤其是那些正确地说,从来没有实现过接口的人得到常数)


JB *_*zet 24

JLS保证一个类只在第一次使用时加载(使单例初始化变得懒惰),并且类加载是线程安全的(使getInstance方法也是线程安全的)

  • 因为第一次调用getInstance(),JVM将持有holder类.如果另一个线程同时调用getInstance(),JVM将不会再次加载holder类:它将等待第一个线程完成类加载,并在加载和初始化holder类时,两个线程都会看到holder类正确初始化,因此包含唯一的单例实例. (14认同)

Sea*_*oyd 7

是因为VM在实际使用之前没有加载静态类

不只是静态类,任何类.在引用类之前不会加载类.请参阅JLS - 12.4.1发生初始化时

或类似的东西,所以我们在转向getInstance()方法之前不创建对象?

究竟.

那个方法线程安全只是在初始化对象的程度吗?

分发引用是线程安全的,因此这种方法始终是线程安全的,而不仅仅是在创建时