《设计模式》之(一)单例模式 - 创建型

生活就要奋斗

单例模式,按目的来分属于创建型模式。是指一个类只有一个实例,该实例对象必须由该单例类自行创建。其特点:1.构造器私有化;2.只有一个实例对象;3.由单例类自行创建;4.对外提供一个全局的访问方法。目的为了节省内存资源、保证数据内容的一致性。直接看代码,代码中注释,简便易懂,如下:

<一>懒汉式单例模式:

/**
 * 懒汉式单例:类加载时不生成实例对象,第一次去调用getInstance()方方法时,才去创建实例对象。
 */
public class LazySingleton {

    /* 实例对象 */
    private static LazySingleton instance;

    /* 构造器私有 */
    private LazySingleton() {
    }

    /* 对外提供获取单例实例的全局访问方法 */
    public static void getInstance() {
        if (instance == null) {
            instance = new LazySingleton();
        }
    }

    // 以下是懒汉式单例模式的变种:保证线程安全,但每次访问都要同步,影响性能,消耗更多的资源。
    private static volatile LazySingleton instanceVariant;

    public static synchronized void getInstanceVariant() {
        if (instance == null) {
            instance = new LazySingleton();
        }
    }
}

<二>饿汉式单例模式:

/**
 * 饿汉式单例:类一旦加载就初始化实例,是线程安全的;
 * 但容易产生垃圾(当没有调用这个实例时,由于该单例在类创建的同时就初始化了一个静态的对象,所以容易造成内存空间的浪费)
 */
public class HungrySingleton {
    /* 实例对象 */
    private static final HungrySingleton instance = new HungrySingleton();

    /* 构造器私有 */
    private HungrySingleton() {
    }

    /* 供外部调用的方法 */
    public static HungrySingleton getInstance() {
        return instance;
    }
}

<三>双重校验锁单例模式:

/**
 * 双重校验锁单利:线程安全,延迟初始化
 */
public class DoubleLockSingleton {

    /* volatile关键字能够禁止指令重排,保证在写操作没有完成之前不能调用读操作 */
    private static volatile DoubleLockSingleton instance;

    /* 构造器私有化 */
    private DoubleLockSingleton() {
    }

    /* 双重检验:第一次避免进入锁,减少性能开销;第二次进行同步,避免多线程问题,防止生成多个对象;
     * 由于JVM中创建对象可能导致重排序,在多线程访问下会存在问题,使用volatile修饰变量,禁止指令重排,有效解决这个问题 */
    private static DoubleLockSingleton getInstance() {
        if (instance == null) {
            synchronized (DoubleLockSingleton.class) {
                if (instance == null) {
                    instance = new DoubleLockSingleton();
                }
            }
        }
        return instance;
    }
}

<四>静态内部类单例模式:

/**
 * 静态内部类单例:充分利用了静态内部类的特点。只有第一次调用getInstance()方法时,
 * JVM才加载内部类实例化instance对象,只有一个线程可以获取对象的初始化锁,保证单例对象唯一,是线 
 * 程安全的。这也是目前比较推荐的方式。
 */
public class StaticInnerSingleton {

    /* 构造器私有 */
    private StaticInnerSingleton() {
    }

    /* 静态内部类:在此创建单例对象 */
    private static class SingletonInstance {
        private static final StaticInnerSingleton instance = new StaticInnerSingleton();
    }

    /* 对外提供获取单例实例的全局访问方法 */
    public static StaticInnerSingleton getInstance() {
        return SingletonInstance.instance;
    }
}

<五>枚举单例模式:

/**
 * 枚举单例:是线程安全的。充分利用了枚举的特性,简单且高效。
 * 实际开发中枚举单例模式还是用到的比较少
 */
public enum EnumerateSingleton {

    INSTANCE;

    /* 可以省略此方法,通过Singleton.INSTANCE进行操作*/
    public static EnumerateSingleton getInstance() {
        return EnumerateSingleton.INSTANCE;
    }

}

注:欢迎指教!

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章