CAS,compare and swap的缩写,中文翻译成比较并交换。
我们都知道,在java语言之前,并发就已经广泛存在并在服务器领域得到了大量的应用。所以硬件厂商老早就在芯片中加入了大量直至并发操作的原语,从而在硬件层面提升效率。在intel的CPU中,使用cmpxchg指令。
在Java发展初期,java语言是不能够利用硬件提供的这些便利来提升系统的性能的。而随着java不断的发展,Java本地方法(JNI)的出现,使得java程序越过JVM直接调用本地方法提供了一种便捷的方式,因而java在并发的手段上也多了起来。而在Doug Lea提供的cucurenct包中,CAS理论是它实现整个java包的基石。
1. CAS:
CAS 操作包含三个操作数 —— 内存位置(V)、预期原值(A)和新值(B)。 如果内存位置的值与预期原值相匹配,那么处理器会自动将该位置值更新为新值 。否则,处理器不做任何操作。无论哪种情况,它都会在 CAS 指令之前返回该 位置的值。(在 CAS 的一些特殊情况下将仅返回 CAS 是否成功,而不提取当前 值。)CAS 有效地说明了“我认为位置 V 应该包含值 A;如果包含该值,则将 B 放到这个位置;否则,不要更改该位置,只告诉我这个位置现在的值即可。”
通常将 CAS 用于同步的方式是从地址 V 读取值 A,执行多步计算来获得新 值 B,然后使用 CAS 将 V 的值从 A 改为 B。如果 V 处的值尚未同时更改,则 CAS 操作成功。
类似于 CAS 的指令允许算法执行读-修改-写操作,而无需害怕其他线程同时 修改变量,因为如果其他线程修改变量,那么 CAS 会检测它(并失败),算法 可以对该操作重新计算。
2.非阻塞算法
如果每个线程在其他线程任意延迟(或甚至失败)时都将持续进行操作,就可以说该算法是无等待的。与此形成对比的是,无锁定算法要求仅 某个线程 总是执行操作。(无等待的另一种定义是保证每个线程在其有限的步骤中正确计 算自己的操作,而不管其他线程的操作、计时、交叉或速度。
3.用CAS来实现非阻塞算法
1. package zl.study.concurrency;
2. /**
3. * AtomicInteger的模拟类,主要是用来测试CAS和非阻塞方式加锁
4. * @author peter
5. *
6. */
7. public class SimulatedAtomicInteger {
8. private int value= 0;
9.
10. private int get(){
11. return this.value;
12. }
13. /**
14. * 模拟CAS
15. * @param current
16. * @param next
17. * @return
18. */
19. private synchronized boolean compareAndSet(int current,int next){
20. return current == next?true:false;
21. }
22. /**
23. * 模拟非阻塞算法
24. * @return
25. */
26. public final int incrementAndGet() {
27. for (;;) {
28. int current = get();
29. int next = current + 1;
30. if (compareAndSet(current, next))
31. return next;
32. }
33. }
34. }
需要注意的是这个方法中的CAS是在jav代码实现的,这个并没有包含内存位置。在concurrent包中,是JNI的方式,内存位置也作为参数传入这个JNI方法中,在后面碰到了在做详细的介绍
在后面介绍java 5提供的并发工具时,我们还能经常看到类似于SimulatedAtomicInteger得写法,大家可以好好体会!
标签:Java,--,next,current,CAS,int,线程,java,多线程 From: https://blog.51cto.com/u_16087105/6223576