Java 线程 (十):CAS
- public?final?int?incrementAndGet()?{?? 
- ????for?(;;)?{?? 
- ????????int?current?=?get();?? 
- ????????int?next?=?current?+?1;?? 
- ????????if?(compareAndSet(current,?next))?? 
- ????????????return?next;?? 
- ????}?? 
- }?? 
[java]? view plain copy print ?
- public?final?int?decrementAndGet()?{?? 
- ????for?(;;)?{?? 
- ????????int?current?=?get();?? 
- ????????int?next?=?current?-?1;?? 
- ????????if?(compareAndSet(current,?next))?? 
- ????????????return?next;?? 
- ????}?? 
- }?? 
以这两个方法为例,incrementAndGet 方法相当于原子性的++i,decrementAndGet 方法相当于原子性的--i(根据第一章和第二章我们知道++i 或--i 不是一个原子性的操作),这两个方法中都没有使用阻塞式的方式来保证原子性(如 Synchronized),那它们是如何保证原子性的呢,下面引出 CAS。
==============================================================================
CAS 指的是现代 CPU 广泛支持的一种对内存中的共享数据进行操作的一种特殊指令。这个指令会对内存中的共享数据做原子的读写操作。简单介绍一下这个指令的操作过程:首先,CPU 会将内存中将要被更改的数据与期望的值做比较。然后,当这两个值相等时,CPU 才会将内存中的数值替换为新的值。否则便不做操作。最后,CPU 会将旧的数值返回。这一系列的操作是原子的。它们虽然看似复杂,但却是 Java 5 并发机制优于原有锁机制的根本。简单来说,CAS 的含义是“我认为原有的值应该是什么,如果是,则将原有的值更新为新值,否则不做修改,并告诉我原来的值是多少”。(这段描述引自《Java 并发编程实践》)
简单的来说,CAS 有 3 个操作数,内存值 V,旧的预期值 A,要修改的新值 B。当且仅当预期值 A 和内存值 V 相同时,将内存值 V 修改为 B,否则返回 V。这是一种乐观锁的思路,它相信在它修改之前,没有其它线程去修改它;而 Synchronized 是一种悲观锁,它认为在它修改之前,一定会有其它线程去修改它,悲观锁效率很低。下面来看一下 AtomicInteger 是如何利用 CAS 实现原子性操作的。
[java]? view plain copy print ?
- private?volatile?int?value;?? 
首先声明了一个 volatile 变量 value,在 第二章我们知道 volatile 保证了变量的内存可见性,也就是所有工作线程中同一时刻都可以得到一致的值。
[java]? view plain copy print ?
- public?final?int?get()?{?? 
- ????return?value;?? 
- }?? 
[java]? view plain copy print ?
- //?setup?to?use?Unsafe.compare 
AndSwapInt?for?updates??
- private?static?final?Unsafe?unsafe?=?Unsafe.getUnsafe();?? 
- private?static?final?long?valueOffset;//?注意是静态的?? 
- static?{?? 
- ??try?{?? 
- ????valueOffset?=?unsafe.objectFieldOffset?? 
- ????????(AtomicInteger.class.getDeclaredField("value"));//?反射出 value 属性,获取其在内存中的位置?? 
- ??}?catch?(Exception?ex)?{?throw?new?Error(ex);?}?? 
- }?? 
- public?final?boolean?compareAndSet(int?expect,?int?update)?{?? 
- ??return?unsafe.compareAndSwapInt(this,?valueOffset,?expect,?update);?? 
- }?? 












 
    
评论