zoukankan      html  css  js  c++  java
  • 【线程安全】—— 单例类双重检查加锁(double-checked locking)

    1. 三个版本单例类的实现

    • 版本1:经典版

      public class Singleton {
          public static Singleton getInstance() {
              if (instance == null) {
                  // 进入 if 之后(也就是 instance 为空时),此时如果另外一个进程刚好执行到 instance = new Singleton(); 则破坏了单例类的唯一性;      
                  instance = new Singleton();
              }
              return instance;
          }
          private Singleton() {}
          private static Singleton instance;
      }

      缺陷:非线程安全,当一个线程进入 getInstance() 方法的 if 判断,而未创建赋值新的对象实例之前,另外一个线程进入 if 判断,将产生两个“单例”对象;

    • 版本2:同步版

      public class Singleton {
          public static synchronized Singleton getInstance () {
              if (instance == null) {
                  instance = new Singleton();
              }
              return instance;
          }
      }

      synchronized 关键字保证了,每一个方法进入该方法之前,都要等到其他方线程离开该方法。

      该方法的缺陷在于,低效。事实上,只在第一次实例化对象时,需要加锁,或者叫同步(版本2方法,每次都要进行加锁验证)。后续获取实例时,多个线程是可以进入同时进入该方法的,因为 if 判断必然通不过,直接返回单例实例。

    • 版本3:双重检查加锁:

      public class Singleton {
          private volatile static Singleton instance;
          public static Singleton getInstance () {
              if (instance == null) {
                  synchronized (Singleton.class) {
                      if (instance == null) {
                          instance = new Singleton();
                      }
                  }
              }
              return instance;
          }
      }

    2. 使用 lock 机制(C++ 版)

    class Singleton {
        private:
            volatile Singleton* pInst = 0;
        public:
            static Singleton* GetInstance() {
                if (pInst == 0) {
                    lock();
                    if (pInst == 0) {
                        pInst = new Singleton();
                    }
                    unlock();
                }
                return pInst;
            }
    }

    同步机制(synchronized)等价于锁机制;

  • 相关阅读:
    vscode开发vue项目保存时自动执行lint进行修复
    React学习笔记-生命周期函数
    react 学习笔记
    iview的Affix组件滚动时没有按照预期固定
    iview input实现默认获取焦点并选中文字
    修改 浏览器滚动轴样式
    node连接mysql数据库
    mysql图形化管理工具workbench下载安装以及基本使用
    mysql 8.0版本下载安装以及默认密码修改
    节流和防抖 区别和实现
  • 原文地址:https://www.cnblogs.com/mtcnn/p/9421240.html
Copyright © 2011-2022 走看看