volatile 与 JVM 指令重排序

前言:

  在做单例模式时 有博客在评论区 推荐使用 volatile 关键字 进行修饰

然后用了两天时间查资料看文档 发现涉及的面太广

虽然已经了解为什么要使用 volatile + synchronized 来写单例模式  但是限于目前的水平有限 无法很好的进行个人总结故 转发一篇 总结得很不错的博客。留备今后复习。

博文地址:<a>http://www.cnblogs.com/dolphin0520/p/3920373.html</a>

时间: 2024-10-11 03:58:24

volatile 与 JVM 指令重排序的相关文章

指令重排序

在多线程并发编程的过程中,执行重排序有时候会造成错误的后果,比如一个线程在main线程中调用setFlag(true)的前边修改了某些程序配置项,而在t1线程里需要用到这些配置项,所以会造成配置缺失的错误.但是java给我们提供了一些抑制指令重排序的方式. 1.同步代码抑制指令重排序 将需要抑制指令重排序的代码放入同步代码块中: 在获取锁的时候,它前边的操作必须已经执行完成,不能和同步代码块重排序:在释放锁的时候,同步代码块中的代码必须全部执行完成,不能和同步代码块后边的代码重排序. 2.vol

Java的多线程机制系列:不得不提的volatile及指令重排序(happen-before)

一.不得不提的volatile volatile是个很老的关键字,几乎伴随着JDK的诞生而诞生,我们都知道这个关键字,但又不太清楚什么时候会使用它:我们在JDK及开源框架中随处可见这个关键字,但并发专家又往往建议我们远离它.比如Thread这个很基础的类,其中很重要的线程状态字段,就是用volatile来修饰,见代码 /* Java thread status for tools, * initialized to indicate thread 'not yet started' */   p

JVM并发机制的探讨——内存模型、内存可见性和指令重排序

[转]http://my.oschina.net/chihz/blog/58035 文章写的非常好,为作者点赞. JAVA内存模型 对于我们平时开发的业务应用来说,内存应该是访问速度最快的存储设备,对于频繁访问的数据,我们总是习惯把它们放到内存缓存中,有句话不是说么,缓存就像是清凉油,哪里有问题就抹一抹.但是CPU的运算速度比起内存的访问速度还要快几个量级,为了平衡这个差距,于是就专门为CPU引入了高速缓存,频繁使用的数据放到高速缓存当中,CPU在使用这些数据进行运算的时候就不必再去访问内存.但

关于volatile的可见性和禁止指令重排序的疑惑

在学习volatile语义的可见性和禁止指令重排序的相关测试中,发现并不能体现出禁止指令重排序的特性 实验代码如下 package com.aaron.beginner.multithread.volatiletest; import java.util.concurrent.CountDownLatch; /** * @author * @description 一句话描述该文件的用途 * @date 2017-03-01 */ public class VolatileAndNonVolat

volatile为什么可以保证内存可见性及防止指令重排序?

内存 共享主存和高速缓存(工作内存).CPU高速缓存(L1,2)产生原因读写主存没有CPU执行指令快,他是某个CPU独有,只与该CPU运行的线程有关. 内存可见性 简单的说,CPU对数据的修改,对其他CPU立刻可见.下面我们详细地说. CPU修改数据,首先对工作内存修改,再同步主内存.单线程中,变量在工作内存的副本一直有效,CPU不用每次修改从主存读取变量,只是每次修改后同步主存. 对其他CPU立刻可见.当一个CPU修改变量,同步主存,如果其他CPU的工作内存也缓存这个变量,那么这个CPU的变量

深入浅出 Java Concurrency (4): 原子操作 part 3 指令重排序与happens-before法则[转]

在这个小结里面重点讨论原子操作的原理和设计思想. 由于在下一个章节中会谈到锁机制,因此此小节中会适当引入锁的概念. 在Java Concurrency in Practice中是这样定义线程安全的: 当多个线程访问一个类时,如果不用考虑这些线程在运行时环境下的调度和交替运行,并且不需要额外的同步及在调用方代码不必做其他的协调,这个类的行为仍然是正确的,那么这个类就是线程安全的. 显然只有资源竞争时才会导致线程不安全,因此无状态对象永远是线程安全的. 原子操作的描述是: 多个线程执行一个操作时,其

多线程之指令重排序

为什么会乱序 现在的CPU一般采用流水线来执行指令.一个指令的执行被分成:取指.译码.访存.执行.写回.等若干个阶段.然后,多条指令可以同时存在于流水线中,同时被执行. 指令流水线并不是串行的,并不会因为一个耗时很长的指令在"执行"阶段呆很长时间,而导致后续的指令都卡在"执行"之前的阶段上. 相反,流水线是并行的,多个指令可以同时处于同一个阶段,只要CPU内部相应的处理部件未被占满即可.比如说CPU有一个加法器和一个除法器,那么一条加法指令和一条除法指令就可能同时处

JVM的重排序

重排序一般是编译器或执行时环境为了优化程序性能而採取的对指令进行又一次排序执行的一种手段.重排序分为两类:编译期重排序和执行期重排序,分别相应编译时和执行时环境. 在并发程序中,程序猿会特别关注不同进程或线程之间的数据同步.特别是多个线程同一时候改动同一变量时,必须採取可靠的同步或其他措施保障数据被正确地改动.这里的一条重要原则是:不要如果指令运行的顺序,你无法预知不同线程之间的指令会以何种顺序运行. 可是在单线程程序中,通常我们easy如果指令是顺序运行的,否则能够想象程序会发生什么可怕的变化

深入浅出 Java Concurrency (4): 原子操作 part 3 指令重排序与happens-before法则

转: http://www.blogjava.net/xylz/archive/2010/07/03/325168.html 在这个小结里面重点讨论原子操作的原理和设计思想. 由于在下一个章节中会谈到锁机制,因此此小节中会适当引入锁的概念. 在Java Concurrency in Practice中是这样定义线程安全的: 当多个线程访问一个类时,如果不用考虑这些线程在运行时环境下的调度和交替运行,并且不需要额外的同步及在调用方代码不必做其他的协调,这个类的行为仍然是正确的,那么这个类就是线程安