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对象的写操作,一定在对其后续的读操作前完成。

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

  • 相关阅读:
    systemmap 使用记录
    reading code record
    吞吐问题
    debug cps 原因
    fopen的a+和rewind
    debug cps && perf debug
    tfo以及quic的阅读笔记
    ss 和netstat
    debug open files
    多核编程 local global
  • 原文地址:https://www.cnblogs.com/zqiguoshang/p/6628701.html
Copyright © 2011-2022 走看看