text: volatile变量提供了线程的可见性，并不能保证线程安全性和原子性。
  锁提供了两种主要特性：互斥(mutualexclusion)和可见性(visibility)。互斥即一次只允许一个线程持有某个特定的锁，因此可使用该特性实现对共享数据的协调访问协议，这样，一次就只有一个线程能够使用该共享数据。可见性要更加复杂一些，它必须确保释放锁之前对共享数据做出的更改对于随后获得该锁的另一个线程是可见的--如果没有同步机制提供的这种可见性保证，线程看到的共享变量可能是修改前的值或不一致的值，这将引发许多严重问题。
  volatile相当于synchronized的弱实现，也就是说volatile实现了类似synchronized的语义，却又没有锁机制。它确保对volatile字段的更新以可预见的方式告知其他的线程。
  (1)Java存储模型不会对valatile指令的操作进行重排序：这个保证对volatile变量的操作时按照指令的出现顺序执行的。
  (2)volatile变量不会被缓存在寄存器中(只有拥有线程可见)或者其他对CPU不可见的地方，每次总是从主存中读取volatile变量的结果。也就是说对于volatile变量的修改，其它线程总是可见的，并且不是使用自己线程栈内部的变量。也就是在happens-before法则中，对一个valatile变量的写操作后，其后的任何读操作理解可见此写操作的结果。
  尽管volatile变量的特性不错，但是volatile并不能保证线程安全的，也就是说volatile字段的操作不是原子性的，volatile变量只能保证可见性(一个线程修改后其它线程能够理解看到此变化后的结果)，要想保证原子性，目前为止只能加锁!
  实际上，这些条件表明，可以被写入volatile变量的这些有效值独立于任何程序的状态，包括变量的当前状态。
  第一个条件的限制使volatile变量不能用作线程安全计数器。虽然增量操作(x++)看上去类似一个单独操作，实际上它是一个由读取-修改-写入操作序列组成的组合操作，必须以原子方式执行，而volatile不能提供必须的原子特性。实现正确的操作需要使x的值在操作期间保持不变，而volatile变量无法实现这点。(然而，如果将值调整为只从单个线程写入，那么可以忽略第一个条件。)
  大多数编程情形都会与这三个条件的其中之一冲突，使得volatile变量不能像synchronized那样普遍适用于实现线程安全。清单1显示了一个非线程安全的数值范围类。它包含了一个不变式--下界总是小于或等于上界。
  也许实现volatile变量的规范使用仅仅是使用一个布尔状态标志，用于指示发生了一个重要的一次性事件，例如完成初始化或请求停机。
  很多应用程序包含了一种控制结构，形式为"在还没有准备好停止程序时再执行一些工作",如清单2所示：