首页 > 其他 > 详细

单例的五种实现

时间:2021-02-21 23:31:34      阅读:16      评论:0      收藏:0      [点我收藏+]

单例的五种实现

1. 立即加载:类加载

// 类加final防止子类覆盖方法 破坏单例性质
public final class Singleton1 implements Serializable {
    // 构造方法私有 但仍可以通过反射创建对象
    private Singleton1() {}
    // 类加载时初始化 由JVM保证线程安全(立即加载)
    private static final Singleton1 INSTANCE = new Singleton1();

    public static Singleton1 getInstance() {
        return INSTANCE;
    }

    // 防止反序列化破坏单例
    private Object readResolve() {
        return INSTANCE;
    }
}

2. 立即加载:枚举类

/**
 * 枚举类实现单例 无法用反射和反序列化破坏单例
 */
public enum Singleton2 {
    // 本质上时枚举类的静态成员变量(立即加载) public static final ...
    INSTANCE;
}

3. 懒加载:锁

// 懒加载
public final class Singleton3 {

    private Singleton3() {}

    private static Singleton3 INSTANCE;

    // 由锁(锁对象为Singleton3.class)来保证原子性和可见性
    // 缺点是之后每次获取对象时都需要进行同步
    public static synchronized Singleton3 getInstance() {
        if (INSTANCE == null) {
            INSTANCE = new Singleton3();
        }
        return INSTANCE;
    }
}

4. 懒加载:DCL

// DCL 懒加载
public final class Singleton4 {

    private Singleton4() {}

    private static volatile Singleton4 INSTANCE;

    // 加锁只存在于第一次创建单例对象时 之后的获取都不用加锁
    public static Singleton4 getInstance() {
        if (INSTANCE != null) {
            return INSTANCE;
        }
        // double check的原因时因为可能由多个线程都会到达这里
        // 如:线程t1 t2 t1获得锁 进入设置后 t2也会进入同步代码块
        synchronized (Singleton4.class) {
            // 所以这里不再检验一遍就无法保证单例
            if (INSTANCE != null) {
                return INSTANCE;
            }
            // volatile保证了字节码执行的有序性(通过读屏障和写屏障)
            // 可以避免出现先赋值 后执行构造方法的情况(此时会导致其他线程看到未构造完成的对象)
            INSTANCE = new Singleton4();
            return INSTANCE;
        }
    }
}

5. 懒加载:内部类

// 内部类懒加载
public final class Singleton5 {

    private Singleton5() {}

    private static Singleton5 INSTANCE;

    public static Singleton5 getInstance() {
        return LazyHolder.INSTANCE;
    }

    // 内部类在第一次被调用时加载
    private static class LazyHolder {
        static final Singleton5 INSTANCE = new Singleton5();
    }
}

单例的五种实现

原文:https://www.cnblogs.com/jefferyyang/p/14427578.html

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!