zoukankan      html  css  js  c++  java
  • 设计模式(二):单例模式(DCL及解决办法)

    public class Singleton {
        //懒汉模式   双重检查锁定DCL(double-checked locking)
        //缺点:由于jvm存在乱序执行功能,DCL也会出现线程不安全的情况。(DCL失效问题)
    
        // jdk1.6及之后,只要定义为private volatile static SingleTon instance 就可解决DCL失效问题。
        // volatile确保instance每次均在主内存中读取,这样虽然会牺牲一点效率,但也无伤大雅。
        // volatile可以保证即使java虚拟机对代码执行了指令重排序,也会保证它的正确性。
        private volatile static Singleton instance;  //延迟加载,需要时才创建实例
    
        private Singleton() {  //私有化构造函数
        } 
    
        public static Singleton getInstance() {
            if (instance == null) { //只有第一次调用时,才需要同步判断(此时instance未初始化,为null)。一旦instance初始化完成,就不需要了
                synchronized (Singleton.class) {  //只要锁住new即可,不需要放在外面getInstance()方法上
                    if (instance == null) {  //二次判断,为了避免线程一在创建实例之后,线程二进来也创建了新实例
                        instance = new Singleton();
                    }
                }
            }
            return instance;
        }
    }
      
    DCL及解决办法 说明:
    针对延迟加载法的同步实现所产生的性能低的问题,可以采用DCL,即双重检查加锁(Double Check Lock)的方法来避免每次调用getInstance()方法时都同步。

    Double-Checked Locking看起来是非常完美的。但是很遗憾,根据Java的语言规范,上面的代码是不可靠的。
    出现上述问题, 最重要的2个原因如下:
    1, 编译器优化了程序指令, 以加快cpu处理速度.
      2, 多核cpu动态调整指令顺序, 以加快并行运算能力.

    问题出现的顺序:
    1, 线程A, 发现对象未实例化, 准备开始实例化
      2, 由于编译器优化了程序指令, 允许对象在构造函数未调用完前, 将共享变量的引用指向部分构造的对象, 虽然对象未完全实例化, 但已经不为null了.
      3, 线程B, 发现部分构造的对象已不是null, 则直接返回了该对象.

    解决办法:
    可以将instance声明为volatile,即 private volatile static Singleton instance
    在线程B读一个volatile变量后,线程A在写这个volatile变量之前,所有可见的共享变量的值都将立即变得对线程B可见。

    更深入理解DCL原理,请查看:Java内存模型 https://blog.csdn.net/wuzhiwei549/article/details/80006533?utm_source=copy
  • 相关阅读:
    golang 简单的实现内 网 穿 透,用户访问本地服务。
    golang 创建一个简单的广播echo服务器
    golang 使用 protobuf 的教程
    golang语言中os包的学习与使用(文件,目录,进程的操作)
    【原】画流程图工具visio使用技巧汇总
    【改】IOS-百度地图API用点生成线路、导航、自定义标注 2013年11月更新
    【原】xcode5&IOS7及以下版本免证书真机调试记录
    【转】C++的拷贝构造函数深度解读,值得一看
    【转】c++中引用的全方位解读
    【转】self.myOutlet=nil、viewDidUnload、dealloc的本质剖析
  • 原文地址:https://www.cnblogs.com/shushengyou/p/9802523.html
Copyright © 2011-2022 走看看