对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 ...
随机推荐
- K近邻(k-Nearest Neighbor,KNN)算法,一种基于实例的学习方法
1. 基于实例的学习算法 0x1:数据挖掘的一些相关知识脉络 本文是一篇介绍K近邻数据挖掘算法的文章,而所谓数据挖掘,就是讨论如何在数据中寻找模式的一门学科. 其实人类的科学技术发展的历史,就一直伴随 ...
- CSPS模拟 52
我貌似曾经说过我是个只会做水题的巨型辣鸡.. 这次证明我水题都不会做.. T1 平均数 区间数$n^2$ 枚举是不可能了 可是好像没有无用的计算量.. 刚想到这里,此时开考15min 看见天皇比手势说 ...
- 我把数表A了
真kx 之前打一棵沙雕主席树,复杂度和正解一毛一样,结果常数爆炸了! 我一直天真的认为卡卡常这题就能AC,然后卡常卡到死也没A掉,极限数据大概跑了1.1s 今天终于打正解了,离线处理,可以用常数更小的 ...
- noip11 string
这道题改题时我打了个玄学复杂度的暴力,然后我成功的造了一组数据hack掉了自己的代码.... 通过观察,我们可以很容易的发现在操作几次后,整个序列就会变成一块一块相同的字母. 于是我们可以对我们的暴力 ...
- jQuery 触发事件 移动端和pc端的区别
jQuery 触发事件 移动端和pc端的区别 <pre>mousedown event.pageXmousemove event.pageXmouseup event.pageXtouch ...
- Java线程池中线程的状态简介
首先明确一下线程在JVM中的各个状态(JavaCore文件中) 1.死锁,Deadlock(重点关注) 2.执行中,Runnable(重点关注) 3.等待资源,Waiting on condition ...
- python脚本 环境准备
现在的公司用 Python 做 Web 开发,入职到现在为止(三个月),算是入门了 Python Web 开发 但是 Python 本身是脚本语言,我还从来没有体会到脚本语言能给日常工作带来的便利 就 ...
- 替换"marquee",实现无缝滚动
js的marquee标签,可以实现元素循环滚动,但是不能无缝连接,要实现“无缝滚动”的效果必须使用js(借鉴百度),思路是使要滚动元素相对位置不断改变,上下滚动就相对top或者bottom,左右滚动就 ...
- python3 控制安卓手机的飞行模式遇到的问题汇总
一.首先调通电脑对手机能落实 adb shell命令 验证通过标准:控制wifi开关的命令,能让wifi功能开启和关闭 (adb shell svc wifi enable 和 adb she ...
- beyong Compare4解决30天的评估期结束
刚开始是删掉注册表的CacheId(无效) 1.在搜索栏中输入 regedit ,打开注册表2.删除项目CacheId :HKEY_CURRENT_USER\Software\Scooter Soft ...