-
volatile可见性5
我在学习volatile的时候,知道它的作用是保证线程的可见性,意思是说当共享变量发生改变时,其它线程可以见。但我不明白其它线程可见是什么意思?
例如共享变量x=0加了volatile这个关键字; A,B两个线程
A读到x=0;
B也读到x=0;
A做了加一操作,此时x=1。那么B线程也应该知道x=1;
可是B做加一操作时,x也等于1。
那么我想知道这个B线程知道了x已经改变是什么意思?最好有个volatile例子能说明下。
我突然想到是这个可能:
因为x=x+1不是原子操作,分二个步骤,加操作和赋值操作。
当B的加操作比A线程快一步,但B的赋值操作比A线程慢一步时
B已经用0做完了加操作得到的结果是1,但是没赋值给x。
A已经做完了加操作,x值此时已经更新到主内存中。
按照可见性,B重新读取x=1。此时B线程内x=1,是从主内存中更新的。
再做赋值操作把B线程做的加操作结果赋值给x,x=1。
所以出现2个1。
不知道我突然想出的步骤是不是正确的,希望大家指导。
问题补充: 我在学习volatile的时候,知道它的作用是保证线程的可见性,意思是说当共享变量发生改变时,其它线程可以见。但我不明白其它线程可见是什么意思?
例如共享变量x=0加了volatile这个关键字; A,B两个线程
A读到x=0;
B也读到x=0;
A做了加一操作,此时x=1。那么B线程也应该知道x=1;
可是B做加一操作时,x也等于1。
那么我想知道这个B线程知道了x已经改变是什么意思?最好有个volatile例子能说明下。
我突然想到是这个可能:
因为x=x+1不是原子操作,分二个步骤,加操作和赋值操作。
当B的加操作比A线程快一步,但B的赋值操作比A线程慢一步时
B已经用0做完了加操作得到的结果是1,但是没赋值给x。
A已经做完了加操作,x值此时已经更新到主内存中。
按照可见性,B重新读取x=1。此时B线程内x=1,是从主内存中更新的。
再做赋值操作把B线程做的加操作结果赋值给x,x=1。
所以出现2个1。
不知道我突然想出的步骤是不是正确的,希望大家指导。
2012年3月15日 17:48
5个答案 按时间排序 按投票排序
-
不加volatile A加1 B可能读到的还是0,这在高并发情况下会出现。
因为有可能会去读一级二级缓存。
volatile使编译器产生的汇编指令, 仅仅从主存操作数据.这样就保证每次都是最新的数据不存在缓存数据。
但是不能保证线程间同步,也就是说A加1跟B加1可能同时发生,也就是x+1这个操作可能被多个线程同时执行。这个是volatile不能保证的。2012年3月15日 18:29
-
A做了加一操作,此时x=1。那么B线程也应该知道x=1;
B知道是有时间间隔的,因为线程间的内存需要先同步到主内存,再同步到其他各个线程的内存上的,这些操作虽然很快,但在多线程下还是有时间 间隔的2012年3月15日 18:09
-
当然要是想深入些可以看看这篇
http://www.ibm.com/developerworks/cn/java/j-jtp02244/2012年3月15日 18:00
-
这个跟JAVA的内存模型关系比较大
每个线程都有自己的内存
一个共享变量(没有被VOLATILE修饰时),主内存,A线程内存,B线程内存都会有一份的(他们之间的同步由虚拟机处理,并且需要消耗时间 ,假设这里有A,B两个线程)
如果被VOLATILE修饰后,这个共享变量就只在主内存,而A线程和B线程内存都不会存放这个共享变量,所以当A线程修改变量时直接操作主内存,B线程读变量时也直接操作主内存,这样B就可以第一时间 知道变量发生变化了
你可以看看这篇文章
http://jiangzhengjun.iteye.com/blog/6525322012年3月15日 17:58
相关推荐
Java并发volatile可见性的验证实现 在Java并发编程中,volatile关键字扮演着非常重要的角色,它可以确保变量的可见性和原子性。在多线程环境下,volatile关键字可以确保变量的修改对其他线程是可见的。本文将通过...
"volatile可见性的一些认识和论证" 本文探讨了Java中volatile关键词的使用和可见性问题,我们将结合JVM内存模型和happen-before概念,来讨论volatile的使用场景和例子。 一、happen-before happen-before是一个...
Java并发编程-volatile可见性详解 Java并发编程中,volatile关键字扮演着非常重要的角色,它提供了两个主要功能:可见性和防止指令重排序。在本文中,我们将详细介绍volatile的可见性机制。 可见性是指多个线程...
内存屏障是实现Volatile可见性的重要机制之一。它确保在volatile字段的前后,所有的内存操作都必须在这些操作真正执行之前完成。此外,内存屏障还可以防止指令重排序,确保指令的执行顺序。 在x86架构中,lock指令...
从JUC中的AQS引入,讲解Java volatile与AQS锁内存可见性
1、保证内存可见性 2、防止指令重排 此外需注意volatile并不保证操作的原子性。 (一)内存可见性 1 概念 JVM内存模型:主内存和线程独立的工作内存 Java内存模型规定,对于多个线程共享的变量...
本文将探讨三个关键概念:过期数据、锁的可见性以及Volatile关键字的作用。首先,我们来看一下“过期数据”这一问题。 1. 过期数据 在并发环境中,当多个线程共享数据时,如果没有适当的同步机制,一个线程修改的...
- volatile不能替代锁:尽管volatile可以保证可见性,但无法保证原子性。例如,两个线程同时读写一个volatile变量,可能导致数据不一致。 - volatile与指针:如果指针本身是volatile,意味着指针的值(地址)可能...
### 深入解析volatile关键字:保障多线程下的数据一致性与可见性 #### 一、volatile的基本概念 ##### 1.1 可见性 在并发编程领域中,可见性是一个极为重要的概念,它指的是当一个线程修改了一个共享变量的值后,...
本文将从JVM、C++以及汇编语言的角度深入探讨volatile的两大特性:禁止重排序和内存可见性。 1. 禁止重排序 重排序是指编译器和处理器为了优化性能而可能对指令序列进行重新排列的一种行为。在Java中,volatile...
Java中的Volatile关键字详解是Java中的一种关键字,用于保证线程之间的可见性、原子性和有序性。下面是对Java中的Volatile关键字详解的知识点总结: 一、基本概念 1. 可见性:可见性是一种复杂的属性,因为可见性...
volatile 变量具有 synchronized 的可见性特性,但是不具备原子特性。这就是说线程能够自动发现 volatile 变量的最新值。volatile 变量可用于提供线程安全,但是只能应用于非常有限的一组用例:多个变量之间或者某个...
2. **单例模式中的双重检查锁定**:在实现线程安全的单例模式时,`volatile`关键字可以用来保证实例创建过程中的可见性和有序性,避免多线程环境下可能出现的问题。 3. **懒汉式初始化**:在某些情况下,为了避免...
`volatile`关键字在C语言中是一个非常重要的概念,主要用于处理多线程环境或者与硬件交互时的内存可见性问题。它的主要作用是确保对变量的修改能够立即反映到所有线程,防止编译器进行不必要的优化,使得其他线程...
volatile是Java中用于处理多线程并发问题的关键字,它主要提供了两个核心功能:可见性和有序性。在Java内存模型(JMM,Java Memory Model)中,volatile确保了共享变量在被修改后,能够立即对其他线程可见,从而避免...
volatile保证可见性的作用是,多线程访问主内存的某一个资源时,如果某一个线程在自己的工作内存中修改了该资源,并写回主内存,那么JMM内存模型应该要通知其他线程来从新获取最新的资源,来保证最新资源的可见性。...
为了确保不同线程之间数据的一致性和可见性,Java提供了多种机制,其中`volatile`关键字就是一个关键的工具。本篇文章将深入探讨如何通过`volatile`关键字验证线程之间的可见性,并通过示例代码详细解释其工作原理。...
1. **可见性**:当一个线程修改了volatile变量的值,其他线程能够立即看到修改。这意味着volatile变量的修改对于所有线程都是可见的,避免了数据不一致的问题。在多线程环境下,如果多个线程共享一个变量,并且这个...
final语义可以保障变量的不可变性,volatile语义可以保障变量的可见性,而锁语义可以保障多个线程之间的同步。 有序性 有序性是指在多线程环境下,指令的执行顺序能够保障结果的正确性。现代CPU的计算速度远远高于...