对Java单例模式 volatile关键字作用的理解
单例模式是程序设计中经常用到的,简单便捷的设计模式,也是很多程序猿对设计模式入门的第一节课。其中最经典的一种写法是:
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关键字作用的理解的更多相关文章
- Java中volatile关键字你真的理解了吗?
面:你怎样理解volatile关键字时? 我:不加思索的说出,volatile修饰的成员变量,可保证线程可见性.不保证原子性和禁止指令重排. 面:你能谈谈什么是线程可见性吗? 我:各个线程对主内存中共 ...
- Java:volatile 关键字的一点理解
背景 学了六年C#,一直没有使用过 volatile,对多线程编程也是偶尔才会使用,这次学习 Java 又遇到了 volatile,准备稍微深入的了解一下. volatile 的作用? 几乎所有支持这 ...
- Java中volatile关键字及其作用是什么?
在 Java 多线程中如何保证线程的安全性?那我们可以使用 Synchronized 同步锁来给需要多个线程访问的代码块加锁以保证线程安全性.使用 synchronized 虽然可以解决多线程安全问题 ...
- Java中Volatile的作用
Java中Volatile的作用 看了几篇博客,发现没搞懂.可是简单来说,就是在我们的多线程开发中.我们用Volatile关键字来限定某个变量或者属性时,线程在每次使用变量的时候.都会读取变量改动后的 ...
- 【转】java中volatile关键字的含义
java中volatile关键字的含义 在java线程并发处理中,有一个关键字volatile的使用目前存在很大的混淆,以为使用这个关键字,在进行多线程并发处理的时候就可以万事大吉. Java语言 ...
- 转:java中volatile关键字的含义
转:java中volatile关键字的含义 在java线程并发处理中,有一个关键字volatile的使用目前存在很大的混淆,以为使用这个关键字,在进行多线程并发处理的时候就可以万事大吉. Java语言 ...
- Java中Volatile关键字详解 (转自郑州的文武)
java中volatile关键字的含义:http://www.cnblogs.com/aigongsi/archive/2012/04/01/2429166.html 一.基本概念 先补充一下概念:J ...
- java volatile关键字作用及使用场景
1. volatile关键字的作用:保证了变量的可见性(visibility).被volatile关键字修饰的变量,如果值发生了变更,其他线程立马可见,避免出现脏读的现象.如以下代码片段,isShut ...
- [面试必备]深入理解Java的volatile关键字
前言 在Java并发编程中,volatile关键字有着至关重要的作用,在面试中也常常会是必备的一个问题.本文将会介绍volatile关键字的作用以及其实现原理. volatile作用 volatile ...
随机推荐
- html中<button>标签的type
HTML的<button>标签的type主要有三种可选值,reset.submit.button. 其中reset为重置按钮,用于清除form表单的数据:submit为提交按钮,点击后会对 ...
- 「2019.7.22 考试」AC和WA0一步之遥
这卷子还是答的挺惨的. 第一题5min写完了,自认为AC(其实WA了80),第二题推了半天CRT的公式老出错结果发现是程序打错了.第三题打模拟150行结果数组没开够,开大就是0->60的转变.状 ...
- CSPS模拟 88
今天我还是个弟弟. 果然唯有AK不可超越.. T1 决策单调性,暴力上整体二分. 极限数据跑的挺快,可是被n<k的脑残测试点qj了.. T2 又是大模拟! T3 想到剩余同种数量的彩球完全等效 ...
- 【工利其器】Android Lint篇——为Android量身定做的静态代码审查工具
前言 我们在进行代码优化的时候,往往是通过开发者的经验来判断哪些代码可能存在潜在问题,哪些资源的使用不合规范等.实际上Android SDK提供了一款功能非常强大的工具,来帮助开发者自动检测代码的质量 ...
- STL&&用法集合
.....STL是c++里很强势很好用的一系列容器(函数)之类的,之前一直不太会用,所以总是暴毙....想着快比赛了,是时候理一下这些东西了. -1.pair 存放两个基本元素的东西 定义方法: pa ...
- Chrome DevTools调试微信X5内核页面
起因:公司最近在做一个双十一的H5宣传页面,大概需求就是模拟微信视频来电,接通视频后弹出某某明星的视频巴拉巴拉@#%!!!~.看到需求我的第一反应是So easy,正当我码代码码的开心的时候,难题他来 ...
- vue ui九宫格、底部导航、新闻列表、跨域访问
一. 九宫格 九宫格:在mint-ui组件库基于vue框架 mui不是基于vue框架 只是css/js文件 (1)官方网站下载安装包 (2)copy css js fonts[字体图标] src/l ...
- Keras 中间层可视化,附代码详解,以Mnist数字为对象
最近搭建了个Resnet50 的神经网络模型,相看一看中间某一层的输出结果,想感性的感受下逐层提取特征的过程,以数字0为对象,对数字0逐层提取特征,话不多说直接上代码,关于如何搭建Resnet,可以参 ...
- 《计算机网络 自顶向下方法》 第2章 应用层 Part1
常见的应用层协议有哪些? HTTP(HyperText Transfer Protocol):超文本传输协议 FTP(File Transfer Protocol):文件传输协议 SMTP(Sim ...
- PHP中跳出循环break,continue,return,exit的区别
1. return 语句的作用 (1) return 从当前的方法中退出,返回到该调用的方法的语句处,继续执行. (2) return 返回一个值给调用该方法的语句,返回值的数 ...