欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

单例模式最佳实践_The solution of Bill Pugh

程序员文章站 2022-07-12 13:27:51
...

基于Steve Quirk早先的工作,Bill Pugh实现了了一个适合所有版本的JVM、性能良好且线程安全的单例。此实现是依靠JVM对内部静态类&静态成员初始化的顺序(非并行)机制来实现的。 

 

class Singleton
{
  private Singleton()
  {
  }

  private static class LazySingleton
  {
    public static Singleton singleton = new Singleton();
  }

  public static Singleton getInstance()
  {
    return LazySingleton.singleton;
  }
}

该设计的执行流程是:

 (1) 当JVM加载Singleton时,类Singleton首先进行初始化,由于该类并没有任何静态

变量需初始化,所以初始化过程很快完成。

(2)    直到JVM决定LazySingleton必须执行时,定义在Singleton中的静态内部类

LazySingleton才会初始化,也就是Singleton中的静态方法getInstance()被调用时,LazySingleton才会初始化。

(3)    JVM第一次加载并初始化LazySingleton时,静态变量instance通过执行外部类

Singleton的私有构造函数而初始化。由于在JLS(Java Language Specification)中定义内部类初始化阶段是线性的、非并发的(serial, non-concurrent),所以无需再在静态的getInstance()方法中指定任何synchronized锁。

(4)    由于在类的初始化阶段,是以一种线性操作方式来写(而非无序访问)静态变量

singleton,(原文是writes the static variable singleton in a serial operation),所有对getInstance()后续的并发调用,将返回同样正确初始化的instance,而不会导致任何额外的同步负载。

 

一个测试例子:

步骤:

1 构造函数设置为private的

 

2 设置一个static类型的private的内部类,只有一个private的 static的 字段instance--单列的唯一实例

 

3 在static的getInstance方法中,返回2中的内部类的static字段instance--单列的唯一实例

public class TestSingleton
{
  //构造函数 private
  private TestSingleton()
  {
    
  }
  
  //private 的静态内部类(static内部类)
  private static class LazySingleTon
  {
    //静态字段,类TestSingleton的唯一实例
    private static TestSingleton singletonIntance = new TestSingleton(); 
  }
  
  //获取单例的方法
  public static TestSingleton getInstance()
  {
    return LazySingleTon.singletonIntance;
  }
  
  //单例的一个测试方法
  public void testSingletonMethod() 
  {
    System.out.println("testSingletonMethod() ");
  }
  
  public static void main(String[] args)
  {
    TestSingleton onlyOne = getInstance();  //获取单例
    onlyOne.testSingletonMethod();          //执行单例方法
  }
  
}