设计模式之单例模式(二)

上篇我们讲述了单例模式的基本概念 , 并且我们也说了饿汉式,懒汉式,线程安全懒汉式 , 但是则三种写法都还不是我推崇的写法 , 今天我们继续说剩下的三种写法 : Dcl写法 ,内部类写法, 枚举式写法 , 其实也可以一篇写完的 , 但是分个章节可以过渡一下 , 这样也可以让我们休息片刻 , 就想电视剧广告更精彩 !

那我们开始 , Let’s Go !

DCL单例模式

DCL 的意思是什么 ? 为什么叫 DCL , 其实就是 Double Check Lock 的简称 , 我们直接看代码 :

public class DclSingleton {
    //volatile 保证了原子模型,创建类的步骤顺序不变,指令重排序优化
    private static  volatile DclSingleton sDclSingleton = null;

    private DclSingleton() {
    }

    public static DclSingleton getInstance() {
        //避免不必要的同步请求
        if (null == sDclSingleton) {
            //保持同步
            synchronized (DclSingleton.class) {
                //类的初始化操作
                if (null == sDclSingleton) {
                    sDclSingleton=new DclSingleton();
                }
            }
        }
        return sDclSingleton;
    }

}

这里重点解释一下 , 为什么需要多做一次 null == sDclSingleton 的判断 , 就像注释里边的分析一样 , 因为下边我们用同步代码块进行的同步的操作 , 所以我们在他之前可以进行仅一步的空判断 , 避免不必要的同步请求 .

然后我还需要解释一下为什么对 sDclSingleton 还需要多加一个 volatile 的字段来修饰呢 ? 这个我们可以从类的加载机制来解释 , 第一步 sDclSingleton 需要在方法区中存在一个索引 , 第二步 new DclSingleton(); 的操作的时候我们首先要在堆分配一块控件 , 第三步是将堆中的变量指向索引 , 但是 Jvm 有这么一个缺点 , 在线程不安全的情况下 , 在即时编辑器中存在指令重排序优化 , 导致我们上述所说的步骤可能第三步骤在第二步之前 , 第二步在第一步之前 , 所以也会导致线程不安全 , 我们设置 volative 这个字段就是保持变量的原子性 , 禁止即时编辑器中存在指令重排序优化 , 从而解决线程不安全问题 .

内部类写法

在上边介绍的DCL模式 , 已经解决了进一步的解决了不必要的同步请求 , 但是写法上还是不简单 , 这里我们来介绍一个能满足 延时加载 , 线程安全 , 性能优越 , 写法简单的需求 , 这种写法就是内部类写法 , 如果别人问到你单例模式的写法 , 我推荐用这种写法可以省下不少的说辞.

public class InnerClassSingeton {

    private InnerClassSingeton() {
    }

    private static InnerClassSingeton getInstance() {
        return HolderInner.Instance;
    }

    private static class HolderInner {
        public static final InnerClassSingeton Instance = new InnerClassSingeton();
    }
}

因为Jvm的本身的机制 static final 修饰的变量能保证唯一性 , 而且静态内部类没有外部方法调用getInstance()方法的时候 , 不会使用内部类 , 保证了延时加载 , 另外我们没有用同步锁的来保证线程安全 ,性能有很大的提升. 所以我推荐这种写法.

枚举类写法

枚举是利用他本身的一个实例 , 这中写法简单 , 但是可能用的少 , 但是需要注意的一点是不能在写额外的获得实例方法 , 这样就不能保证线程的安全了 , 不能再用你Java本身自带的属性了.

public enum EnumSingleton {
    //定义一个元素,他就是EnumSingleton的一个实例
    INSTANCE;

}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值