The "singleton mode" of design patterns written for myself

Singleton mode

There are many ways to implement singleton mode: hungry man, lazy man, enumeration, static inner class, etc.
Reposted from: https://www.jianshu.com/p/b8c578b07fbc

Why use singleton mode?

Scenario For some classes (mostly tool classes), the entire system only needs one instance to complete the task, such as: log printing class, obtaining thread pool class, etc.

advantage

  • There is only one object in the system, which saves system resources, reduces the overhead of frequently creating and destroying objects, and improves system performance.

Disadvantage

  • If the instantiated object is not used for a long time, it will be considered as garbage by the system and will be recycled, which will result in the loss of the object state.

Method to realize

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

    private static final SingletonHungry instance = new SingletonHungry();

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

    public static SingletonHungry getInstance() {
    
    
        return instance;
    }
}
  • Hungry man mode
/**
 * <懒汉模式>
 * 只有在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;
    }
}

Guess you like

Origin blog.csdn.net/Dkangel/article/details/105579602