zoukankan      html  css  js  c++  java
  • 单例模式

    众所周知(也许有些人不知道),编译器以及CPU会在不影响串行结果的情况下对代码进行重排序,以便加快执行速度。(比如超标量流水线技术)

    这在并发执行中会造成一些问题。以单例模式的DCL写法举例:

    public class Singleton{

      private Singleton(){};

      public static volatile Singleton singleton;

      public static Singleton getSingleton(){

        if(singleton == null){

          synchronized(singleton){

            if(singleton == null){

              singleton = new Singleton();

            }

          }

        }

        return singleton;

      }

    }

    双重检查加锁好理解,一是为了保证单一实例,而是为了减少并发开销。为什么又用了volatile了呢?

    因为橙色标注的部分实际上有三步:

    分配内存,初始化对象, 引用赋值。

    但由于重排序的存在,有可能会先分配内存,然后赋值,最后才初始化。并发下就有可能将未初始化的对象暴露出来。这也是为什么要用volatile的原因。

    jdk1.5后, volatile语义中有了happen-before关系约束。保证了对volatile对象的写操作,一定在对其后续的读操作前完成。

    也就杜绝了这种重排序造成错误的情况。

  • 相关阅读:
    iOS开发之字符串去掉首尾空格换行
    iOS开发之截取UIScrollView长图方法、截长图
    iOS开发之语音录制
    iOS开发之程序各种状态监听
    iOS开发之监听应用进入前台后台
    iOS开发之波浪动画效果
    mysql 主从一致性检查
    git 备份和恢复
    tomcat server.xml配置文件 解析
    检查MySQL主从数据一致性
  • 原文地址:https://www.cnblogs.com/zqiguoshang/p/6628701.html
Copyright © 2011-2022 走看看