jvm-哪位大神解释下[volatile不能保证原子性,也就不能保证线程安全]这句话

问题描述

哪位大神解释下[volatile不能保证原子性,也就不能保证线程安全]这句话

哪位大神解释下[volatile不能保证原子性,也就不能保证线程安全]这句话
哪位大神解释下[volatile不能保证原子性,也就不能保证线程安全]这句话
哪位大神解释下[volatile不能保证原子性,也就不能保证线程安全]这句话

解决方案

简单来说,volatile在多cpu环境下不能保证其它cpu的缓存同步刷新,因此无法保证原子性。

解决方案二:

还是以最常用的i++来说吧,包含3个步骤
1,从内存读取i当前的值
2,加1
3,把修改后的值刷新到内存

对于普通变量来说多线程下1,2之间被中断,其它线程修改了i的值,那原来已经在1,2之间被中断的线程的i的值就已经无效了,所以多线程是不安全的。
另外对于普通变量来说,步骤1并不是每次都会从内存中读取,步骤3也并不会每次都保证会立即刷新到内存,详情见线程缓存的相关文章。
所以这里有两个问题,可见性和原子性,viloate只能保证可见性,即步骤1每次都重新读,步骤3每次都立即刷新到主内存。但1,2之间仍然会被中断,多个线程交叉修改,所以仍然不安全

解决方案三:

原子操作是一些列的操作要么全做,要么全不做。锁机制可以保证原子性。而volatile 是一种弱的同步机制,只能确保共享变量的更新操作及时被其他线程看到,但不能保证原子性,比如线程1,2同时读到最新数据a,然后线程1试图递增变量a时,线程2已经率先修改并提交了,那么线程1操作的数据就是失效数据,导致读-改-写三个本该一起执行的操作失去了原子的含义。

解决方案四:

保证线程安全必须保证顺序性,可见性和原子性。
顺序性,顾名思义,就是必须保证程序是按照你所预想的逻辑执行的。
可见性,写入缓存与从缓存读出是一个完整的动作,保证变化的值即时可见。这是volatile能保证的。
原子性,保证一个处理(或一段代码)不被打断地执行完毕,这是原子性。

原子性和可见性确实容易搞混,可见性比原子性控制范围更小,仅仅控制缓存的一次读写。而原子性控制整段处理。

举个例子:使用volatile声明一个变量 a,然后对变量a做如下操作。
a=a+1;
a=a+b;

volatile无法保证这两条语句不被打断的执行完毕,只有使用同步化关键字保证它的原子性才可以。
以上有个人理解,可能有不完善的地方。大体就是这个意思。

解决方案五:

对于一个被声明为volatile的变量,每次去读这个变量的值时,jvm会先把这个值更新到最新值,再让你读,因此你读到的就是最新值,当时读到之后其它线程
有可能又改了这个变量的值,因此不是原子性,也不是线程安全的。

解决方案六:

为什么volatile不能保证原子性而Atomic可以

时间: 2016-10-11

jvm-哪位大神解释下[volatile不能保证原子性,也就不能保证线程安全]这句话的相关文章

刚开始学习jawa,遇到这个问题,不明白,哪位大神解释下

问题描述 刚开始学习jawa,遇到这个问题,不明白,哪位大神解释下 Exception in thread ""main"" java.lang.IllegalArgumentException: Too many pattern letters: W at java.time.format.DateTimeFormatterBuilder.parsePattern(Unknown Source) at java.time.format.DateTimeFormat

win7 共享文件-哪位大神解释下:win7共享文件夹问题,

问题描述 哪位大神解释下:win7共享文件夹问题, 哪位大神解释下:计算机win7名称:FLASH-PC : 为什么FLASH-PC可以访问本机共享文件,而127.0.0.1却找不到网络路径

helloworld-为生么这个程序几个编译程序都无法显示呀??求大神解释下!!

问题描述 为生么这个程序几个编译程序都无法显示呀??求大神解释下!! public class HelloWorld{ public static void main(String[] args) { int num = 999; int count = 0; for(;(num/10)>1; count++) { ; } System.out.print("它是个"+count+"位的数"); } } 解决方案 for(;(num/10)>1; cou

cpu-求大神解释下NUMA、UMA、SMP这三种CPU架构?

问题描述 求大神解释下NUMA.UMA.SMP这三种CPU架构? 分别对应我们现在常用的哪些机器上使用? 前两个好像只是一个N的区别.. 解决方案 打开机箱,如果你看到有多个插CPU的插座,那就是SMP 如果每个CPU旁边有一组单独的内存插座,那就是NUMA,否则就是UMA 解决方案二: NUMA.SMP都是服务器上用的.PC一般只有1个CPU. 解决方案三: NUMA就是非统一内存访问 UMA就是统一内存访问 普通PC就是UMA. 解决方案四: 在UMA系统中,CPU直接就可以访问所有内存.

java-我想实现一个和数据库同步的Jsp页面,哪位大神指点下?

问题描述 我想实现一个和数据库同步的Jsp页面,哪位大神指点下? 用户需求是,A地点有台计算机,B地点有台计算机,当A地点的计算向数据库插入数据时,B地点的计算机可以立即看到A地点所输入的数据. 解决方案 Spring框架有个定时器http://taiwei-peng.iteye.com/blog/689061 解决方案二: 你的意思是JSP页面数据同步么?web页面刷新写个定时器,定时去查询数据库刷新页面 解决方案三: Dango可以直接实现架设好,基本就可以了

angularjs-这段代码哪里有错啊,运行结果不对啊,哪位大神解决下。

问题描述 这段代码哪里有错啊,运行结果不对啊,哪位大神解决下. <!doctype html> Hello {{ clock}}! function MyController($scope, $timeout) { var updateClock = function() { $scope.clock = new Date(); $timeout(function() { updateClock(); }, 1000); }; updateClock(); }; 运行结果如下: 解决方案 请稍

c#-在Main函数中访问不到Analyze方法 把private改为static就可以哪位大神解释一下

问题描述 在Main函数中访问不到Analyze方法 把private改为static就可以哪位大神解释一下 class Program { static StringBuilder sb = new StringBuilder(); static void Main(string[] args) { Type t4 = typeof(double); Analyze(t4); MessageBox.Show(sb.ToString(), "Analyze of type is " +

java代码-java引用数据类型的问题,请大神解释下标注的问题.....

问题描述 java引用数据类型的问题,请大神解释下标注的问题..... import java.util.Scanner; public class Bank implements Runnable { Acount acount; public Bank(Acount a) -->这个构造方法的含义? { this.acount=a; } public void run() { Scanner input=new Scanner(System.in); System.out.println(&qu

安装打开虚拟串口软件时报错,求大神解释下

问题描述 我在本机上安装了一个虚拟串口软件VSPDXP,但是安装之后点击运行就报错,报错图片如下,求大神解释下,该怎么搞