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

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

      那么我们先说说volatile,volatile可以保证内存的可见性,禁用重排序,但是不能保证操作的原子性,不具备互斥性,那么,什么时候可以用volatile呢?必须同时满足以下三条:

  • 不依赖自己:写变量时并不依赖变量的当前值。
  • 不依赖别人:变量不与其他状态共同组成invariant。
  • 访问变量时,没有其他原因需要加锁。

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

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

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

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

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

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

      synchronized锁不仅仅有“互斥”的功能,将多步操作加锁保证了原子操作,而且还保证了内存可见性

 

转载于:https://my.oschina.net/GinkGo/blog/1560155

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值