text: Java虚拟机试图定义一种Java内存模型（Javememroymodel，JMM）来屏蔽掉各种硬件和操作系统的内存访问差异，以实现让Java程序在各种平台下都能达到一致的内存访问效果。此前，主流程序语言（C/C++）直接使用物理硬件和操作系统的内存模型，因此并发表现无法跨平台。
  Java内存模型的主要目标是定义程序中的各个变量的访问规则，即在虚拟机中将变量存储到内存和从内存中取出变量这样的底层细节。此处的变量指的是实例字段，静态字段和构成数组对象的元素，但不包括局部变量和方法参数，因为后者是线程私有的，不会被共享，自然就不存在竞争问题。
  Java内存模型规定了所有的变量都存储在主内存（MainMemory）中，但是每条线程还拥有自己独立的工作内存（WorkingMemory）。线程中的工作内存保存了该线程使用到的存储在主内存中的变量的副本，线程堆变量的读写操作都必须在工作内存中进行。不同的线程之间无法访问彼此的工作内存。线程变量值的传递需要通过主内存来完成。
  主内存与工作内存的划分，与Java数据分区（堆栈方法区等）并无直接联系。如果非要关联起来，主内存类似于栈堆，而工作内存类似于栈。
  对于如果在工作内存和主内存之间进行同步，JMM定义了下面8种操作，虚拟机在实现时必须保证下面8种操作都是原子的：
  store的值必须之前被assign过。
  只有主内存中可以创建新的变量，use、store一个变量之前，这个变量必须先执行过了assign和load操作。
  一个变量只允许一条线程进行lock操作，但同一条线程可以重复lock多次，但是unlock也必须执行相同次数才能解锁。
  如果一个变量执行lock操作，将会清空工作内存中此变量的值，之后如果要use该变量必须重新进行load和assign。
  线程不允许unlock未被其锁定的变量。
  对一个变量执行unlock之前，必须先把该变量同步会主内存中（store+write）。
  一个变量被描述为volatile后，它具有两种特性：
  保证此变量的修改对所有线程可见（每次读写都从主内存进行同步）。
  但是对volatile的写操作往往会被编译为多条字节码，即使被编译为一条字节码，其底层解释器可能也需要多条指令才能解释，因此volatile的写操作并不能保证具有原子性。
  在某些情况下，volatile的同步机制的性能确实要优于锁。volatile的读操作的性能消耗与普通变量几乎没有什么区别，但是写操作会略慢一些。
  我们可以认为基本数据类型的读写具备原子性。
  如果需要更大范围的原子性保证，Java内存模型提供了lock和unlock操作，虚拟机未把lock和unlock直接开放给用户使用，但是却提供了更高层次的字节码指令monitorenter和monitorexit来隐式使用这两个操作。这两个字节指令对应于Java中的synchronized原语。
  可见性是指当一个线程修改了共享变量的值，其他线程能够立即得知这个修改。JMM是通过在修改变量后将新值同步回主内存，在变量读取前从主内存刷新变量值这种利用主内存作为媒介的方式实现可见性的。
  先行发生原则是JMM中定义的两项操作之间的偏序关系，如果操作A先行发生于操作B，就是说A做出的修改能被B所观察到。
  监视器锁定规则对同一个变量，一个unlock操作先行发生于后面对同一个锁的lock操作。