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

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

为了简单起见为什么Bill Pugh的解决方案比上面的例子更好?

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

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

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

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

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

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

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

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

究竟。

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

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

是因为VM在实际使用之前没有加载静态类或类似的东西,所以在转向getInstance()方法之前我们不创建对象?

正确。

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

它确保只创建一个实例,并且除了对完全初始化的实例的引用之外,没有客户端接收任何内容。

解释的关键部分如下:

与调用getInstance()的时刻相比,之前没有引用嵌套类(因此不会由类加载器加载)。 因此,该解决方案是线程安全的,无需特殊的语言结构(即易失性或同步)。

Bill Pogh的解决方案提供了懒惰。