写给自己看的设计模式之《单例模式》

单例模式

单例模式实现方式很多:饿汉、懒汉、枚举、静态内部类等
转自:https://www.jianshu.com/p/b8c578b07fbc

为什么要用单例模式?

场景 对于一些类(多为工具类)来说,整个系统中只需要一个实例就可以完成任务,比如:日志打印类、获取线程池类等

优点

  • 系统只存在一个对象,可以节约系统资源,减少了频繁创建、销毁对象的开销,提高了系统性能。

缺点

  • 如果实例化的对象长时间不被使用,会被系统认为是垃圾而被回收,这将导致对象状态的丢失。

实现方式

  • 懒汉模式
/**
 * <饿汉模式>
 * <p>
 * 类一旦加载就创建instance实例,getInstance时实例已经存在
 *
 * @author dkangel
 */
public class SingletonHungry {
    
    

    private static final SingletonHungry instance = new SingletonHungry();

    /**
     * 私有构造方法,避免其他类创建实例
     */
    private SingletonHungry() {
    
    
    }

    public static SingletonHungry getInstance() {
    
    
        return instance;
    }
}
  • 饿汉模式
/**
 * <懒汉模式>
 * 只有在getInstance时才去实例化instance
 * <p>
 * <应用场景>
 * 除了初始化单例类时 即 创建单例外,继续延伸出来的是:单例对象 要求初始化速度快 & 占用内存小
 *
 * @author dkangel
 */
public class SingletonLazy {
    
    

    /**
     * volatile 保证指令重排序的正确性
     */
    private volatile static SingletonLazy instance;

    /**
     * 私有构造方法,避免其他类创建实例
     */
    private SingletonLazy() {
    
    
    }

    /**
     * <双重校验锁机制>
     * <p>
     * 第一个if:若实例已经创建,则直接返回,无需加锁
     * <p>
     * 第二个if:避免多次创建实例
     * 如果有两个线程同时调用getInstance()方法,线程A先获取到锁,线程B等待线程A释放锁
     * 当线程A执行instance = new SingletonLazy();完毕,释放了锁,此时线程B获取到锁
     * 假如没有第二个if判空,则线程B也会执行instance = new SingletonLazy();
     * 这样就导致创建了多余的实例
     *
     * @return SingletonLazy
     */
    public static SingletonLazy getInstance() {
    
    
        if (instance == null) {
    
    
            synchronized (SingletonLazy.class) {
    
    
                if (instance == null) {
    
    
                    instance = new SingletonLazy();
                }
            }
        }
        return instance;
    }

    /**
     * <同步锁>
     * <p>
     * 每次访问都要进行线程同步(即 调用synchronized锁)
     * 造成过多的同步开销(加锁 = 耗时、耗能)
     *
     * @return SingletonLazy
     */
    public static synchronized SingletonLazy getInstance1() {
    
    
        if (instance == null) {
    
    
            instance = new SingletonLazy();
        }
        return instance;
    }
}

猜你喜欢

转载自blog.csdn.net/Dkangel/article/details/105579602