单例模式是程序设计中经常用到的,简单便捷的设计模式,也是很多程序猿对设计模式入门的第一节课。其中最经典的一种写法是:

class Singleton {
private volatile static Singleton instance;//volatile关键字防止指令重排
private Singleton(){}
public static Singleton getInstance() {
if ( instance == null ) { //一重判断
synchronized (Singleton.class) {//对Singleton.class上锁
if ( instance == null ) {//二重判断
instance = new Singleton();
}
}
}
return instance;
}
}

  其中有两个关键的地方:1,初始化instance实例的时候,采用两重判断对Singleton.class上锁。

             2,静态变量instance使用了volatile关键字进行修饰。

  第一个问题相对比较好理解  

        if ( instance == null ) { //一重判断
synchronized (Singleton.class) {//对Singleton.class上锁
if ( instance == null ) {//二重判断
instance = new Singleton();
}
}
}

  

  sychronized关键字锁住Singleton类而不是instance对象,是因为,此时instance为空,加sychronized没有意义。
第一重判断的意义在于:如果instance非空,就跳过了锁的步骤,减少加锁的资源开销。但是由于第一重判断在代码锁之外,如果不同线程同时访问到install==null,会先后阻塞执行代码锁内的内容。所以在代码锁内加第二重判断就很有必要了,避免第一个线程获取实例后,第二个线程获得资源锁又执行了一次instance的初始化,产生两个不同的实例。

  很多人不理解instance实例在声明时加volatile关键字的作用,或者是发现别人这么写了,自己也跟着这么写。对volatile关键字的解释,很多地方只是提了句“当要求使用volatile 声明的变量的值的时候,系统总是重新从它所在的内存读取数据,它可以防止指令重排”,这里不想对这句话进行展开解释,想详细了解可以参考文章
  https://www.cnblogs.com/shan1393/p/8999683.html
  https://www.cnblogs.com/xrq730/p/7048693.html

  instance = new Singleton()看上去只有一句话,但java的初始化成员变量包括内存分配、初始化、返回对象在堆上的引用等一系列操作。对于synchronized代码块内,一条语句完整执行是没有问题的。但如果发生了指令重排,先返回对象在堆上的引用,再进行初始化。对于另一个执行到一重判断的线程来说,由于instance已经指向了堆上的一段内存空间,那么instance就不为空,会将未完成初始化的对象返回给其他函数调用,引发一系列不安全隐患。加了volatile关键字,可以保证返回对象在对上的引用发生在初始化之后,避免了这种情况的发生。这就是单例模式下 instance加volatile关键字的作用。

对Java单例模式 volatile关键字作用的理解的更多相关文章

  1. Java中volatile关键字你真的理解了吗?

    面:你怎样理解volatile关键字时? 我:不加思索的说出,volatile修饰的成员变量,可保证线程可见性.不保证原子性和禁止指令重排. 面:你能谈谈什么是线程可见性吗? 我:各个线程对主内存中共 ...

  2. Java:volatile 关键字的一点理解

    背景 学了六年C#,一直没有使用过 volatile,对多线程编程也是偶尔才会使用,这次学习 Java 又遇到了 volatile,准备稍微深入的了解一下. volatile 的作用? 几乎所有支持这 ...

  3. Java中volatile关键字及其作用是什么?

    在 Java 多线程中如何保证线程的安全性?那我们可以使用 Synchronized 同步锁来给需要多个线程访问的代码块加锁以保证线程安全性.使用 synchronized 虽然可以解决多线程安全问题 ...

  4. Java中Volatile的作用

    Java中Volatile的作用 看了几篇博客,发现没搞懂.可是简单来说,就是在我们的多线程开发中.我们用Volatile关键字来限定某个变量或者属性时,线程在每次使用变量的时候.都会读取变量改动后的 ...

  5. 【转】java中volatile关键字的含义

    java中volatile关键字的含义   在java线程并发处理中,有一个关键字volatile的使用目前存在很大的混淆,以为使用这个关键字,在进行多线程并发处理的时候就可以万事大吉. Java语言 ...

  6. 转:java中volatile关键字的含义

    转:java中volatile关键字的含义 在java线程并发处理中,有一个关键字volatile的使用目前存在很大的混淆,以为使用这个关键字,在进行多线程并发处理的时候就可以万事大吉. Java语言 ...

  7. Java中Volatile关键字详解 (转自郑州的文武)

    java中volatile关键字的含义:http://www.cnblogs.com/aigongsi/archive/2012/04/01/2429166.html 一.基本概念 先补充一下概念:J ...

  8. java volatile关键字作用及使用场景

    1. volatile关键字的作用:保证了变量的可见性(visibility).被volatile关键字修饰的变量,如果值发生了变更,其他线程立马可见,避免出现脏读的现象.如以下代码片段,isShut ...

  9. [面试必备]深入理解Java的volatile关键字

    前言 在Java并发编程中,volatile关键字有着至关重要的作用,在面试中也常常会是必备的一个问题.本文将会介绍volatile关键字的作用以及其实现原理. volatile作用 volatile ...

随机推荐

  1. C语言打印年历

    摘要:使用C语言打印年历 最初看到这个是觉得比较有意思,记得读书时候只写过月历,年历要复杂一些,现在水平提高了,来重新写一下吧. 看了网上的一些代码,大都比较繁琐,本文采用全新的思路完成年历打印. 整 ...

  2. C/c.pp:贪心,二分答案

    说是贪心有点牵强. 其次,答案满足单调性,如果在k次操作能完成那么在k+1次操作内也能完成. 因为大不了你就把多的一次对方操作再进行一次就好了. 怎么操作呢? 我们从头扫这个序列,遇到每一个不匹配位置 ...

  3. CSPS模拟 88

    今天我还是个弟弟. 果然唯有AK不可超越.. T1 决策单调性,暴力上整体二分. 极限数据跑的挺快,可是被n<k的脑残测试点qj了.. T2 又是大模拟! T3 想到剩余同种数量的彩球完全等效 ...

  4. P5304旅行者(比bk201还要流氓的解法)

    题目如上. 暴力碾标算,n^2过百万!! 作为一道黑题它确实有点点水(如果是畜生解法的话) 就是找出两两点之间的最短路的最小值. 本来是很高深的一题,要跑两遍最短路啊,然后染色啊,再拓展什么的,但是! ...

  5. 「CF630C」Lucky Numbers

    更好的阅读体验 Portal Portal1: Codeforces Portal2: Luogu Description The numbers of all offices in the new ...

  6. Python实现王者荣耀小助手(二)

    接下来我们获取英雄和武器信息,详细代码KingGlory.py如下(代码中有详细注解): # -*- coding: utf-8 -*- #!/usr/bin/env python # @Time : ...

  7. 开启docker远程访问

    开启docker远程访问 进入到/lib/systemd/system/docker.service vim /lib/systemd/system/docker.service 找到ExecStar ...

  8. Linux基础命令(二)

    6.cp copy 作用:复制文件 选项: -a 复制目录时使用并且可以保持属性不变,属性:属主,属组,权限 -r 复制目录时使用但是不可以保持属性不变 -p 保持属性不变 注意:其实只需要记一个-a ...

  9. element 动态合并表格

    前言 element 官方的例子太简单了,不满足实际的需求 数据肯定是动态的,合并的行数,列数都是动态的,该如何知道每一行的合并数呢 需求 动态合并表格,数据来源于数据库 正文 一开始,我的数据源是单 ...

  10. java编程思想第四版第十一章总结

    1. 容器类被分为两类:Collection和Map Collection是一个接口:包括: List接口: ArrayList:按照被插入顺序保存元素, 查询快, 增删改慢 LinkedList:按 ...