请教一个问题,在JVM高级特性里面,第12章中讲到,“如果要把一个变量从主内存复制到工作内存,那就要顺序地执行read 和 load 操作, 如果要把变量从工作内存同步回主内存,就要顺序执行store 和 write 操作”。 那么volatile是怎么保证 a =4 这种组合操作(store +write)的原子性和有可见性的?
疑惑解析:
引自(http://www.infoq.com/cn/articles/ftf-java-volatile)
在x86处理器下通过工具获取JIT编译器生成的汇编指令来看看对Volatile进行写操作CPU会做什么事情。
Java代码:instance = new Singleton();//instance是volatile变量
汇编代码:
0x01a3de1d: movb $0x0,0x1104800(%esi);
0x01a3de24: lock addl $0x0,(%esp);
有volatile变量修饰的共享变量进行写操作的时候会多第二行汇编代码,通过查IA-32架构软件开发者手册可知,lock前缀的指令在多核处理器下会引发了两件事情。
Lock前缀指令会引起处理器缓存回写到内存。Lock前缀指令导致在执行指令期间,声言处理器的 LOCK# 信号。在多处理器环境中,LOCK# 信号确保在声言该信号期间,处理器可以独占使用任何共享内存。(因为它会锁住总线,导致其他CPU不能访问总线,不能访问总线就意味着不能访问系统内存),但是在最近的处理器里,LOCK#信号一般不锁总线,而是锁缓存,毕竟锁总线开销比较大。在8.1.4章节有详细说明锁定操作对处理器缓存的影响,对于Intel486和Pentium处理器,在锁操作时,总是在总线上声言LOCK#信号。但在P6和最近的处理器中,如果访问的内存区域已经缓存在处理器内部,则不会声言LOCK#信号。相反地,它会锁定这块内存区域的缓存并回写到内存,并使用缓存一致性机制来确保修改的原子性,此操作被称为“缓存锁定”,缓存一致性机制会阻止同时修改被两个以上处理器缓存的内存区域数据。
一个处理器的缓存回写到内存会导致其他处理器的缓存无效。IA-32处理器和Intel 64处理器使用MESI(修改,独占,共享,无效)控制协议去维护内部缓存和其他处理器缓存的一致性。在多核处理器系统中进行操作的时候,IA-32 和Intel 64处理器能嗅探其他处理器访问系统内存和它们的内部缓存。它们使用嗅探技术保证它的内部缓存,系统内存和其他处理器的缓存的数据在总线上保持一致。例如在Pentium和P6 family处理器中,如果通过嗅探一个处理器来检测其他处理器打算写内存地址,而这个地址当前处理共享状态,那么正在嗅探的处理器将无效它的缓存行,在下次访问相同内存地址时,强制执行缓存行填充。
总结:
解决这种问题无非就是加锁,cpu和内存之间是通过系统总线来进行交互的, 简单的办法就是锁系统总线,好点办法是锁缓存。
转载于:https://my.oschina.net/yangshj/blog/1517517
分享到:
相关推荐
Java多线程编程中,原子性、可见...总结来说,原子性、可见性和有序性是Java多线程编程中保证并发安全的重要概念。通过合理使用Java提供的并发工具和关键字,开发者可以有效地管理线程之间的交互,确保程序的正确运行。
本文主要讲解了Java内存模型(JMM)中关于并发编程的三个基本概念:原子性、可见性和有序性。 原子性 原子性是指一个操作不会被线程调度机制打断,一旦开始,就一直运行到结束,中间不会有任何线程切换(context ...
锁提供了严格的互斥和可见性,而`volatile`则是一种较弱的同步机制,只保证可见性。在设计并发程序时,开发者需要根据具体需求选择合适的方法来确保线程安全和数据一致性。理解这些概念有助于编写出高效且可靠的并发...
总结来说,Java内存模型通过原子性、有序性和可见性保证了多线程环境下的数据一致性。理解并熟练运用这些概念是编写高效、线程安全的Java代码的基础。在实际开发中,应根据需求选择合适的方式来确保这三个特性,以...
Java中的Volatile关键字详解是Java中的一种关键字,用于保证线程之间的可见性、原子性和有序性。下面是对Java中的Volatile关键字详解的知识点总结: 一、基本概念 1. 可见性:可见性是一种复杂的属性,因为可见性...
`volatile`关键字提供了可见性保证,但不保证原子性,因此在设计并发程序时,我们需要根据实际情况选择合适的数据同步机制,如`synchronized`、`volatile`、`Atomic`类等,以确保程序的正确性和性能。
1. **使用`synchronized`关键字**:它可以确保同一时刻只有一个线程可以执行指定的代码块,从而保证了原子性和可见性。 2. **使用`Lock`接口**:通过显式地锁定和解锁来实现对资源的独占访问。 3. **使用`volatile`...
- volatile不能替代锁:尽管volatile可以保证可见性,但无法保证原子性。例如,两个线程同时读写一个volatile变量,可能导致数据不一致。 - volatile与指针:如果指针本身是volatile,意味着指针的值(地址)可能...
在Java并发编程中,volatile关键字扮演着非常重要的角色,它可以确保变量的可见性和原子性。在多线程环境下,volatile关键字可以确保变量的修改对其他线程是可见的。本文将通过示例代码详细介绍Java并发volatile可见...
然而,并发编程也带来了一系列挑战,如线程安全、可见性、原子性和有序性问题。 **并发理论基础**: 并发编程的核心在于多线程,允许多个执行单元在同一时间执行任务,以充分利用系统资源。在Java中,通过创建...
1、保证内存可见性 2、防止指令重排 此外需注意volatile并不保证操作的原子性。 (一)内存可见性 1 概念 JVM内存模型:主内存和线程独立的工作内存 Java内存模型规定,对于多个线程共享的变量...
并发编程的三大特性包括原子性、可见性和有序性。这些特性是理解和解决并发问题的基础。 1. 原子性:原子性保证了一个操作或者一系列操作在执行过程中不会被其他线程打断,即操作要么全部完成,要么全部不完成,...
通过对`volatile`关键字的工作原理及其在多线程环境中的应用进行深入探讨,我们可以更好地理解如何利用`volatile`来解决可见性和有序性问题。同时,我们也应该注意到`volatile`并不能保证操作的原子性,因此在需要...
volatile是Java虚拟机提供的轻量级的同步机制,它有三个特性:保证可见性、不保证原子性、禁止指令重排。 1、volatile保证可见性 volatile保证可见性的作用是,多线程访问主内存的某一个资源时,如果某一个线程在...
- **非原子性**:需要注意的是,虽然`volatile`关键字提供了可见性和有序性保证,但它并不能保证复合操作的原子性。例如,对于`i++`这样的操作,即使`i`是`volatile`变量,该操作也不是原子性的。 #### 五、使用...
- **非原子性**:`volatile`变量虽然保证了可见性,但是并不能保证原子性。也就是说,对于复合操作(如`i++`),`volatile`并不能确保这些操作不会被拆分成多个步骤执行。这可能导致数据不一致性问题。 #### 三、...
2. volatile仅保证数据的可见性和有序性,而不保证原子性,而synchronized则是全面的同步机制,既保证可见性又保证原子性。 3. volatile不会导致线程阻塞,而synchronized可能会使线程进入等待状态,影响性能。 4. ...
总结来说,`volatile`关键字是Java并发编程中的一种轻量级同步机制,它可以解决多线程环境下的可见性问题,但不能保证原子性。正确理解和使用`volatile`关键字,可以帮助开发者编写出更加高效且可靠的并发程序。
java 并发中的原子性与可视性实例详解 Java 并发中的原子性与可视性是两个非常重要的概念,它们都是...我们可以使用volatile修饰变量来保证可见性,但是volatile不能保证原子性。我们需要使用同步技术来保证原子性。
总的来说,`volatile`关键字在Java中用于解决多线程环境下的可见性和有序性问题,但不能保证原子性。在编写多线程程序时,我们需要结合使用`volatile`、`synchronized`以及原子类来实现线程安全的数据访问,以确保...