设计模式:单例模式(Singleton Pattern)

16uni 2021年04月21日 4,482次浏览

保证在内存中只有一个实例存在

1.饿汉式

/**
 * 饿汉式
 * 类加载到内存后,就实例化一个单例,JVM保证线程安全
 * 简单实用,推荐使用!
 * 缺点:不管用到与否,类装载时就完成实例化
 */
public class Singleton {

    private static final Singleton INSTANCE = new Singleton();

    private Singleton() {};

    public static Singleton getInstance() {

        return INSTANCE;
    }
}

2.懒汉式,线程不安全(一)

/**
 * 懒汉式
 * 虽然达到了按需初始化的目的,但多线程访问时会有问题
 * 如果多线程访问,当一个线程调用getInstance方法时,判断INSTANCE 为空,但是这个线程还没new一个实例出来,另一个线程也调用了getInstance方法,此时INSTANCE同样为空,第二个线程也会继续new一个Singleton实例,此时两个实例不是同一个实例。
 */
public class Singleton {
    private static Singleton INSTANCE;

    private Singleton() {}

    public static Singleton getInstance() {
	//调用getInstance时判断INSTANCE是否为空,为空才初始化
        if (INSTANCE == null) {
            
            INSTANCE = new Singleton();
        }
        return INSTANCE;
    }
}

3.懒汉式,线程安全(二)

/**
 * 懒汉式
 * 可以通过synchronized解决,但也带来效率下降
 */
public class Singleton {

    private static Singleton INSTANCE;

    private Singleton() {}

    public static synchronized Singleton getInstance() {

        if (INSTANCE == null) {

            INSTANCE = new Singleton();
        }
        return INSTANCE;
    }
}

4.懒汉式(三)

public class Singleton {

    private static Singleton INSTANCE;

    private Singleton() {
    }

    public static Singleton getInstance() {

        if (INSTANCE == null) {

            //妄图通过减小同步代码块的方式提高效率,然后不可行
            synchronized (Singleton.class) {

                INSTANCE = new Singleton();
            }
        }
        return INSTANCE;
    }
}

5.懒汉式,双重校验锁(四)

public class Singleton {

    private static volatile Singleton INSTANCE; 

    private Singleton() {}

    public static Singleton getInstance() {

        if (INSTANCE == null) {

            //双重检查
            synchronized (Singleton.class) {

                if(INSTANCE == null) {

                    INSTANCE = new Singleton();
                }
            }
        }
        return INSTANCE;
    }
}

6.静态内部类方式

/**
 * 静态内部类方式
 * JVM保证单例
 * 加载外部类时不会加载内部类,这样可以实现懒加载
 * 完美单例
 */
public class Singleton {

    private Singleton() {}

    private static class SingletonHolder {

        private final static Singleton INSTANCE = new Singleton();
    }

    public static Singleton getInstance() {

        return SingletonHolder.INSTANCE;
    }
}

7.枚举单例

/**
 * 不仅可以解决线程同步,还可以防止反序列化。
 * 完美中的完美。
 */
public enum Singleton {

    INSTANCE;

    public static void main(String[] args) {

        Singleton.INSTANCE;
    }
}