博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
单例模式
阅读量:5359 次
发布时间:2019-06-15

本文共 720 字,大约阅读时间需要 2 分钟。

众所周知(也许有些人不知道),编译器以及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对象的写操作,一定在对其后续的读操作前完成。

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

转载于:https://www.cnblogs.com/zqiguoshang/p/6628701.html

你可能感兴趣的文章
NOIP2002pj产生数[floyd 高精度]
查看>>
POJ2955Brackets[区间DP]
查看>>
[整体二分]【学习笔记】【更新中】
查看>>
log4j(二)——如何控制日志信息的输出?
查看>>
NYOJ -37回文字符串
查看>>
LeetCode Arithmetic Slices
查看>>
iperf详细介绍~!《转》
查看>>
bzoj3145:[Feyat cup 1.5]Str
查看>>
[数据结构]一元n次多项式的抽象数据类型
查看>>
ABAP术语-ABAP Editor
查看>>
软件开发工程师的20条编程经验
查看>>
25个令人难忘的广告设计
查看>>
【转】tcpdump的使用
查看>>
interllij13新建maven web工程
查看>>
Fiddle 抓包工具
查看>>
jq一些常用的交互效果
查看>>
Aspose.Word 操作word复杂表格 拆分单元格 复制行 插入行 文字颜色
查看>>
java项目用SpringMVC+mybatis中的配置文件详解
查看>>
Ajax原理(收藏)
查看>>
VS2010发布,IIS实际目录,无法修改只读状态解难决办法
查看>>