原子变量、volatile、synchronized的可见性和原子性比较

      jdk5提供了java.util.concurrent包,这个包并行功能强大,工具齐全,其中就包括原子变量atomicjava

      那么咱们先说说volatile,volatile能够保证内存的可见性,禁用重排序,可是不能保证操做的原子性,不具有互斥性,那么,何时能够用volatile呢?必须同时知足如下三条:算法

  • 不依赖本身:写变量时并不依赖变量的当前值。
  • 不依赖别人:变量不与其余状态共同组成invariant。
  • 访问变量时,没有其余缘由须要加锁。

       只解释一下第一条,“不依赖本身的当前值”,举个简单的例子:count++, 这个就叫依赖当前值。为何要有这样的限制?由于,volatile不保证count++是原子的,即咱们所说的“互斥执行”,虽然咱们过去的例子都把一条代码看成一个动做,但相信你知道,一条代码在CPU那里多半不会是一条指令,好比count++其实会分解为load-modify-store三个更小的动做,若是这样的操做有多个线程在作,是极易出错的。工具

     原子变量的特色在于其原子性的CAS(compare-and-swap)操做,由此能够完成volatile所不能的“check-and-act”动做,同时它能够保证内存的可见性,“可见性”只不过是其稍带脚支持的功能而已。atom

      Java.util.concurrent中实现的原子操做类包括:AtomicBoolean、AtomicInteger、AtomicLong、AtomicReference。另外其底层就是volatile和CAS 共同做用的结果:spa

     1.首先使用了volatile 保证了内存可见性。线程

     2.而后使用了CAS(compare-and-swap)算法 保证了原子性。排序

     其中CAS算法的原理就是里面包含三个值:内存值A  预估值V  更新值 B  当且仅当 V == A 时,V = B; 不然,不会执行任何操做。内存

      synchronized锁不单单有“互斥”的功能,将多步操做加锁保证了原子操做,并且还保证了内存可见性变量

相关文章
相关标签/搜索