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并发的了解程度, ...
随机推荐
- mysql之结果集去重
mysql操作中,经常会遇到对结果集的去重 本篇文章列出几种应对办法: 1.使用distinct做去重,测试了一下,DISTINCT可以支持多列去重 select DISTINCT user_id_t ...
- QQ消息群发助手(超级简单)
大家好!我开发的小工具,效果见动图: 下载地址 QQ群发助手.rar 代码: def Login(): global Flag try: bot.Login(['-q',v1.get()]) tkin ...
- SpringBoot中使用task实现定时任务
定时任务实现的几种方式: Timer:这是java自带的java.util.Timer类,这个类允许你调度一个java.util.TimerTask任务.使用这种方式可以让你的程序按照某一个频度执行, ...
- Java设计模-过滤器模式
过滤器模式 过滤器模式(Filter Pattern)或标准模式(Criteria Pattern)是一种设计模式,这种模式允许开发人员使用不同的标准来过滤一组对象,通过逻辑运算以解耦的方式把它们连接 ...
- Xming+SecureCRT的安装与使用
博主本人平和谦逊,热爱学习,读者阅读过程中发现错误的地方,请帮忙指出,感激不尽 Xming下载地址:https://xming.en.softonic.com/ 安装完后打开文件位置: 一.Xming ...
- iText 中文无法显示
/** * 导出PDF工具com.lowagie.itext测试 * * @param response * @throws IOException * @throws DocumentExcepti ...
- 用R的dplyr进行数据转换(一)
在网上找了很久关于数据转换的,都没有找到比较好的.现在为大家整理一下.按照我自己的思路.当然也是为了自己做笔记. 为了方便,大家可以统一安装一个系列的包,这个只需要安装tidyverse这个包就可以, ...
- 将js进行到底:node学习3
node重要API之NET--TCP编程之旅 废话:最近去了一趟上海会了会一个程序员朋友,途径SNH48握手会,说好我就去看看,没想到握手了王诗蒙,掉入巨坑:塞纳河.回来后边听着<春夏秋冬> ...
- linux安装fasttext报错,升级gcc后成功解决
首先说一下存在问题: 本人打算在linux安装一个fasttext用来训练词向量,本来是想要从gensim来调用fasttext的,但是加载大的本地txt一直不对,没办法了只好在linux安装一个fa ...
- HEALER
项目介绍: 专注是一款时间管理应用,可以帮你管理时间,制定计划,让你保持专注,从快节奏的当下抽离,进入另一个平和安静的时空,以获得更好的工作和学习效率. 主模块(专注):设置分类.专注时长.简介,点击 ...