剑指Offer-2-实现Singleton模式


常用模式中唯一一个能够用短短几十行代码完整实现的模式
由于要求只能设置一个实例,把构造函数设为私有以禁止他人创建实例

推荐的解法1:静态构造函数

public sealed class Singleton{
    private Singleton(){}
    // 私有构造方法
    private static Singleton instance = new Singleton();
    // 实例化了(唯一)一个对象,它是私有的
    public static Singleton Instance{
        get{
            retrun instance;
        }
    }
}

静态构造函数会在类型第一次被使用的时候被调用
如果没用调用该属性,而是调用了类型的某个静态方法(不需要实例),同样会过早地创建实例

推荐的解法2

public sealed class Singleton{
    private Singleton(){}
    // 私有构造方法

    public static Singleton Instance{
        get{
            retrun Nested.instance;
        }
    }
    class Nested{
        static Nested(){}
        internal static readonly Singleton instance = new Singleton();
    }
}

内部定义了一个私有类型Nested
如果不调用属性Singleton.Instance,就不会触发调用Nested,也不会创建实例

其实就是说私有类型不会像属性一样在类型第一次被使用自动调用静态构造函数的时候被创建

接下来看看Java

饿汉式

类一旦加载,就把单例初始化完成,保证getInstance的时候,单例是已经存在的了。

public class Singleton {     
    private Singleton() {}    
    // 私有构造方法,保证外界无法直接实例化。 
    private static Singleton instance = new Singleton();
      
    // 通过公有的静态方法获取对象实例
    public static Singleton getInstace() { 
        return instance;
    } 
}

懒汉式

只有当调用getInstance的时候,才回去初始化这个单例

public class Singleton {      
    // 私有构造方法,保证外界无法直接实例化。     
    private Singleton() {}

    private static Singleton instance = null;   

    // 通过公有的静态方法获取对象实例   
    public static Singleton getInstace() {         
        if (instance == null) {             
            instance = new Singleton();         
        }         
        return instance;     
    } 
}

但是这个实现只适用于单线程环境,即这是线程不安全的
多线程下线程安全的实现倒是很简单粗暴,就是在方法前面加上synchronized关键字
我在想有没有像《剑指Offer》上推荐的一样,更高级的写法