volatile关键字的理解
volatile是java语言提供的一种稍弱的同步机制,它的作用是能够保证被volatile修饰的变量,每个线程在获取它的值时都能获取到最新的值。
要理解这个原理首先要知道java内存模型:每个线程都有自己的工作内存,线程对变量的所有操作都必须在工作内存中进行 。每个线程都会将运算需要的数据从主内存复制一份到自己的工作内存,等运算结束之后才会刷新到主内存中。

理解了上述模型,就会发现在并发情况下可能会出现数据不一致的现象,例如线程1和线程2同时从主内存中复制了一个变量a=1到自己的工作内存,但是期间线程1先对a进行了操作将值改为2,之后线程2中仍然按照a等于旧值1进行运算,这显然会出现问题。
于是有了volatile关键字:当一个线程改变了某个变量的值,就会通知其他线程:你们的缓冲区(工作内存)中变量的值已经发生改变了,请重新从主内存中读取新的值。volatile并不意味着线程每次都会去主内存中获取最新的值!
volatile只能保证变量在各个线程中的可见性,但不能保证变量操作的原子性。意思就是volatile只能保证每个线程在读取到的变量值是最新的,但是不能保证线程对变量的计算、自增等行为的原子性,即即使线程获取到了最新的值,但是在非原子性操作过程中,变量的值仍有可能被其他线程修改。
volatile的适用场景
通常来说,使用volatile必须具备以下2个条件:
1)对变量的写操作不依赖于当前值
2)该变量没有包含在具有其他变量的不变式中
通俗来说,就是只有保证对变量的操作具有原子性,才能保证使用volatile关键字的程序在并发时能够正确执行。 值得注意的是变量自增i++,不具有原子性
下面列出两个现实开发中常用的使用场景:
1.状态量flag
public class MyThread extends Thread{
private volatile static boolean flag = true;
@Override
public void run() {
while (!flag){
doSomething;
}
}
}
线程中需要对一个状态量进行判断然后doSomething,这个时候一旦其他线程修改了flag状态,另外一个线程立马就能感知到
2.双重校验(单例模式)
public class Singleton {
private volatile static Singleton singleton;
//创建Singleton实例的方法
public Singleton getInstance(){
if(singleton == null){
synchronized(Singleton.class){
if(singleton == null){
singleton = new Singleton();
}
}
}
return singleton;
}
}
这里可能有人不理解为什么在synchronized代码块中还需要判断一次singleton是否为null?,当内存中没有singleton实例时,也就是singleton == null,假如有两个线程1,2同时判断singleton == null为true,那么都会进入if代码块,线程1获取到锁并执行了创建singleton实例的代码,线程1释放锁,线程2获得锁,如果不加singleton == null的判断,那么线程而会在创建一次single同对象,也就不符合单例模式的规则了。
volatile关键字的理解的更多相关文章
- volatile关键字深入理解
前言: 这个关键字的重点就三个字,就是可见性.但是面试的时候,你说出可见性三个字,基本上满分100的话,最多只能得到20分.剩下的那80分,就要靠你用硬功夫去获得了. 所谓的硬功夫,其实就是要整明白, ...
- java中volatile关键字的理解
一.基本概念 Java 内存模型中的可见性.原子性和有序性.可见性: 可见性是一种复杂的属性,因为可见性中的错误总是会违背我们的直觉.通常,我们无法确保执行读操作的线程能适时地看到其他线程写入的值,有 ...
- 谈谈对volatile关键字的理解
1. volatile的特性 volatile是Java语言提供的一种轻量级的同步机制,用来确保将变量得更新操作通知到其它线程.具备三种特性: 保证变量的可见性: 对于volatile修饰的变量进行单 ...
- java volatile关键字的理解
转载:http://shmilyaw-hotmail-com.iteye.com/blog/1672779 一个多线程的示例引发的问题 在讨论这个关键字之前先看一个多线程的示例代码: public c ...
- 对volatile关键字的理解
本文是基于对 http://www.cnblogs.com/aigongsi/archive/2012/04/01/2429166.html 这篇文档的理解 volatile 用volatile修饰的 ...
- java并发编程 volatile关键字 精准理解
1.volatile的作用 一个线程共享变量(类的成员变量.类的静态成员变量等)被volatile修饰之后,就具有以下作用: 1)并发中的变量可见性(不同线程对该变量进行操作时的可见性),即一个线程修 ...
- 面试官最爱的volatile关键字
在Java相关的岗位面试中,很多面试官都喜欢考察面试者对Java并发的了解程度,而以volatile关键字作为一个小的切入点,往往可以一问到底,把Java内存模型(JMM),Java并发编程的一些特性 ...
- Java面试官最常问的volatile关键字
在Java相关的职位面试中,很多Java面试官都喜欢考察应聘者对Java并发的了解程度,以volatile关键字为切入点,往往会问到底,Java内存模型(JMM)和Java并发编程的一些特点都会被牵扯 ...
- 面试必问的volatile关键字
原文: 卡巴拉的树 https://juejin.im/post/5a2b53b7f265da432a7b821c 在Java相关的岗位面试中,很多面试官都喜欢考察面试者对Java并发的了解程度, ...
随机推荐
- 虚拟环境(virtualenv)
为什么需要虚拟环境: 到目前位置,我们所有的第三方包安装都是直接通过pip install xx的方式进行安装的,这样安装会将那个包安装到你的系统级的Python环境中.但是这样有一个问题,就是如果你 ...
- CAS 5.3.x 相关信息
CAS 5.3.x 相关信息 单点登录系统 学习网站: https://www.apereo.org/projects/cas 官方网站 https://github.com/apereo/cas-o ...
- C++ List的用法
Lists将元素按顺序储存在链表中. 与 向量(vectors)相比, 它允许快速的插入和删除,但是随机访问却比较慢. assign() 给list赋值 back() 返回最后一个元素 begin() ...
- 吴裕雄--天生自然Android开发学习:Android studio 3.5安装详解
3. 建立AVD(安卓虚拟设备) 点击右上角AVD Manager图标,单击按钮Create Virtual Device,选择Nexus 5X,下一步,选择版本9.0,Download,然后Next ...
- mybatis generator 使用教程(生成带注释的实体类)
引言: 最近的一个项目,由于数据库表巨多,导致需要创建N多个java实体.dao.mapper.xml映射文件,如果均使用纯手工编写,无疑需要耗费大量时间和精力.于是上网学习了mybatis gene ...
- ZOJ-1163-The Staircases
dp[i][j]表示i个砖头构成的最高台阶不高于j的楼梯数目 Accepted 1163 C++11 0 2280 #include "bits/stdc++.h" using n ...
- algorithm-question
主键都相同,选择排序和插入排序谁快 选择排序:比较N*(N-1)/2,交换0:插入排序:比较N-1,交换0:插入排序更 大专栏 algorithm-question快 逆序数组,插入排序与选择排序 ...
- 千万不要在module里扩展较多逻辑,很容易引起项目异常。
NOP项目 为保持紧跟NOP更新,项目组坚持不改NOP源码. 以触发器,插件化开发为拓展模式 NOP自定义好的接口或完全独立的新拓展功能很容易插件化. 但部分功能要在NOP原项目上扩展修改在不改源码的 ...
- js 实现排序算法 -- 快速排序(Quick Sort)
原文: 十大经典排序算法(动图演示) 快速排序 快速排序的基本思想:通过一趟排序将待排记录分隔成独立的两部分,其中一部分记录的关键字均比另一部分的关键字小,则可分别对这两部分记录继续进行排序,以达到整 ...
- geoserver整合swagger2支持自动生成API文档
网上各种博客都有关于swagger2集成到springmvc.springboot框架的说明,但作者在整合到geoserver中确碰到了问题,调试一番最后才解决,遂总结一下. swagger2集成只需 ...