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

基于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();          //执行单例方法
  }
  
}

 

 

你可能感兴趣的:(线程安全,静态内部类,单列模式)