JVM规范但愿定义一套java内存模型(java memory model,JMM),使得java程序在不一样的硬件平台下面都能展示出一致的内存访问机制。
java内存模型规定全部变量保存在主内存中,每一个线程有本身的工做内存。线程的工做内存中保存了该线程使用到的变量的主内存拷贝,线程对变量的全部操做都必须在工做内存中进行,而不能直接读写主内存中的变量。不一样的线程之间没法直接访问对方的工做内存,需经过主内存才能进行变量的传递。java内存模型围绕原子性、有序性、可见性三个方面展开。
java
关于变量在工做内存和主内存之间的传递,java内存模型定义了如下8种原子操做:架构
volatile变量保证了可见性与有序性,volatile变量的操做也须要遵循一些特殊的规则:jvm
先行发生原则:线程
JVM指令是基于栈的指令架构,与之相对的是基于寄存器的指令,如x86平台。基于栈的指令集的优势是可移植,缺点是执行速度慢。
下面的基于栈的指令例子中,也有load、store等操做,这些属于工做内存中的操做,与内存之间的那8种原子操做不同。
咱们可使用javap -c去获取java代码的字节码。字节码是运行在JVM上的指令。咱们翻译一段简单的程序。看看基于栈的指令是如何工做的。翻译
public int calc() { int a = 100; int b = 200; int c = 300; return (a+b)*c; }
public int calc(); Code: 0: bipush 100 2: istore_1 3: sipush 200 6: istore_2 7: sipush 300 10: istore_3 11: iload_1 12: iload_2 13: iadd 14: iload_3 15: imul 16: ireturn
我试着去比较带volatile的程序和不带volatile的程序,javap以后显示,它们的字节码是没有区别的。若是咱们再深刻一层去看JIT以后的跟CPU强相关的指令,应该会发现不一样。3d