Java volatile 关键字 理解

Java   volatile 理解

Volatile

1 如果一个字段被申明为volatile,那么Java内存模型则可以保证多个线程所看到的值是一致的

2  禁止指定重排。

3  volatile只能保证可见性,不能保证原子性

可见性实现原理:

volatile能够保证可见性,那么它是如何实现可见性的呢?以X86处理器为例,在对volatile修饰的变量进行写操作时,通过编译器生成反汇编指令后,会发现会多一条Lock前缀,就是由于这条Lock前缀所实现的可见性。Lock前缀在多核处理器中会引发下面这两件事情:

Lock指令会将当前处理器缓存行的数据写回到主内存。(ps:每个处理器都有自己的cache缓存,每次缓存中操作的变量都是主内存中变量的拷贝)

一个处理器写回主内存的操作会造成其他处理的缓存无效。

举个栗子

一个变量i被volatile修饰,两个线程想对这个变量修改,都对其进行自增操作也就是i++,i++的过程可以分为三步,首先获取i的值,其次对i的值进行加1,最后将得到的新值写会到缓存中。

线程A首先得到了i的初始值100,但是还没来得及修改,就阻塞了,这时线程B开始了,它也得到了i的值,由于i的值未被修改,即使是被volatile修饰,主存的变量还没变化,那么线程B得到的值也是100,之后对其进行加1操作,得到101后,将新值写入到缓存中,再刷入主存中。根据可见性的原则,这个主存的值可以被其他线程可见。

问题来了,线程A已经读取到了i的值为100,也就是说读取的这个原子操作已经结束了,所以这个可见性来的有点晚,线程A阻塞结束后,继续将100这个值加1,得到101,再将值写到缓存,最后刷入主存,所以即便是volatile具有可见性,也不能保证对它修饰的变量具有原子性。

原文地址:https://www.cnblogs.com/yxlawyer/p/11632764.html

时间: 2024-08-26 11:29:13

Java volatile 关键字 理解的相关文章

Java线程工作内存与主内存变量交换过程及volatile关键字理解

Java线程工作内存与主内存变量交换过程及volatile关键字理解 1. Java内存模型规定在多线程情况下,线程操作主内存变量,需要通过线程独有的工作内存拷贝主内存变量副本来进行.此处的所谓内存模型要区别于通常所说的虚拟机堆模型: 2. 线程独有的工作内存和进程内存(主内存)之间通过8中原子操作来实现,如下图所示: 原子操作的规则(部分): 1) read,load必须连续执行,但是不保证原子性. 2) store,write必须连续执行,但是不保证原子性. 3) 不能丢失变量最后一次ass

13、Java并发性和多线程-Java Volatile关键字

以下内容转自http://tutorials.jenkov.com/java-concurrency/volatile.html(使用谷歌翻译): Java volatile关键字用于将Java变量标记为“存储在主存储器”中.更准确地说,这意味着,每个读取volatile变量将从计算机的主存储器中读取,而不是从CPU缓存中读取,并且每个写入volatile变量的写入将被写入主存储器,而不仅仅是写入CPU缓存. 实际上,由于Java 5的volatile关键字保证不仅仅是volatile变量被写入

Java volatile关键字简读

Java volatile关键字解读-多变的,易变的 volatile访问内存内存模型: - 1.常用变量是由主内存加载到缓存,线程进一步获取变量内容. - 2.volatile每次访问直接访问主内存cpu,保证缓存一致性,实现轻量级同步 Demo public class VolatileDemo { private static volatile boolean flag = false; public static void main(String[] args){ Thread thre

从根源上解析 Java volatile 关键字的实现

1.解析概览 内存模型的相关概念 并发编程中的三个概念 Java内存模型 深入剖析Volatile关键字 使用volatile关键字的场景 2.内存模型的相关概念 缓存一致性问题.通常称这种被多个线程访问的变量为共享变量. 也就是说,如果一个变量在多个CPU中都存在缓存(一般在多线程编程时才会出现),那么就可能存在缓存不一致的问题. 为了解决缓存不一致性问题,通常来说有以下2种解决方法: 通过在总线加LOCK#锁的方式 通过缓存一致性协议 这2种方式都是硬件层面上提供的方式. 上面的方式1会有一

Java Volatile关键字 以及long,double在多线程中的应用

概念: volatile关键字,官方解释:volatile可以保证可见性.顺序性.一致性. 可见性:volatile修饰的对象在加载时会告知JVM,对象在CPU的缓存上对多个线程是同时可见的. 顺序性:这里有JVM的内存屏障的概念,简单理解为:可以保证线程操作对象时是顺序执行的,详细了解可以自行查阅. 一致性:可以保证多个线程读取数据时,读取到的数据是最新的.(注意读取的是最新的数据,但不保证写回时不会覆盖其他线程修改的结果) 每一个线程运行时都有一个线程栈,线程栈保存了线程运行时候变量值信息.

Java volatile 关键字

前言: 用在多线程,同步变量.线程为了提高效率,将某个成员(A)变量拷贝了一份(B),线程中对A的访问其实访问的是B.只在某些动作时才进行A和B的同步.因此存在A和B不 一致的情况.volatile就是用来避免这个中情况的.volatile告诉jvm,它所修饰的变量不保留拷贝,直接访问主内存中的A.在Java内存模型中,有main memory,每个线程也 有自己的memory(寄存器).为了性能,一个线程会在自己的memory中保持要访问的变量的副本.这样就会出现同一个变量在某个瞬时,在一个线

java volatile关键字

用在多线程,同步变量. 线程为了提高效率,将某成员变量(如A)拷贝了一份(如B),线程中对A的访问其实访问的是B.只在某些动作时才进行A和B的同步.因此存在A和B不一致的情况.volatile就是用来避免这种情况的.volatile告诉jvm, 它所修饰的变量不保留拷贝,直接访问主内存中的(也就是上面说的A) =========================分割线1================================= 版权声明 :转载时请以超链接形式标明文章原始出处和作者信息及本

(转)java volatile关键字

转自:http://www.cnblogs.com/aigongsi/archive/2012/04/01/2429166.html 参考:http://blog.csdn.net/imzoer/article/details/8620801 java中volatile关键字的含义 在java线程并发处理中,有一个关键字volatile的使用目前存在很大的混淆,以为使用这个关键字,在进行多线程并发处理的时候就可以万事大吉. Java语言是支持多线程的,为了解决线程并发的问题,在语言内部引入了 同

Java volatile关键字解惑

volatile特性 内存可见性:通俗来说就是,线程A对一个volatile变量的修改,对于其它线程来说是可见的,即线程每次获取volatile变量的值都是最新的. volatile的使用场景 通过关键字sychronize可以防止多个线程进入同一段代码,在某些特定场景中,volatile相当于一个轻量级的sychronize, 因为不会引起线程的上下文切换,但是使用volatile必须满足两个条件: 1.对变量的写操作不依赖当前值,如多线程下执行a++,是无法通过volatile保证结果准确性