在计算机科学中,比较和交换(Conmpare And Swap)是用于实现多线程同步的原子指令 它将内存位置的内容与给定值进行比较,只有在相同的情况下,将该内存位置的内容修改为新的给定值 这是作为单个原子操作完成的 原子性保证新值基于最新信息计算; 如果该值在同一时间被另一个线程更新,则写入将失败 操作结果必须说明是否进行替换; 这可以通过一个简单的布尔响应(这个变体通常称为比较和设置),或通过返回从内存位置读取的值来完成(摘自维基本科),我来为大家讲解一下关于ca和cap有什么不同?跟着小编一起来看一看吧!
ca和cap有什么不同
在计算机科学中,比较和交换(Conmpare And Swap)是用于实现多线程同步的原子指令。 它将内存位置的内容与给定值进行比较,只有在相同的情况下,将该内存位置的内容修改为新的给定值。 这是作为单个原子操作完成的。 原子性保证新值基于最新信息计算; 如果该值在同一时间被另一个线程更新,则写入将失败。 操作结果必须说明是否进行替换; 这可以通过一个简单的布尔响应(这个变体通常称为比较和设置),或通过返回从内存位置读取的值来完成(摘自维基本科)
CAS可以有效的提升并发的效率,但同时也会引入ABA问题。
CAS其实就是实现一种乐观的自旋锁,相较于synchronize的悲观锁,没有阻塞状态,自然也就没有上下文的切换了,而线程状态的切换,耗时比CAS的自旋比较操作耗时大得多。
原子性是什么?原子性就是最小单位,原子性操作就是最小的操作,无法再进一步分割,这操作的结果只有2种,完成或者未完成。例如 int a = 1,这种就是原子性操作。而a ,这个就不是原子性操作,因为a ,会拆解为3步,读取a的值,a增加1,再把a的值刷新。
还是那个例子,2个线程,同时对一个变量a进行递增,每次 1,递增100次。当2个线程都执行完毕,a的结果不会是200,会小于200。
解决办法?第一时间就会想到加个锁,因为锁能保证一段代码块执行完毕,从而保证原子性。但是,如果要执行的代码足够简单的时候,例如上面的只有个a ,使用锁的话,会十分浪费,性能也不高,因为一个线程获得了锁,其他线程都无法进行了。所以,就需要用到了CAS
怎样工作的:初始AtomicInteger的值为0线程A执行:var5 = this.getIntVolatile(var1,var2);获取的结果为:0线程A被暂停线程B执行:var5 = this.getIntVolatile(var1,var2);获取的结果为:0线程B执行:this.compareAndSwapInt(var1,var2,var5,var5 var4)线程B成功将AtomicInteger中的值改为1线程A恢复运行,执行:this.compareAndSwapInt(var1,var2,var5,var5 var4),此时线程A使用var1和var2从AtomicInteger中获取的值为:1,而传入的var5为0,比较失败,返回false,继续循环。线程A执行:var5 = this.getIntVolatile(var1,var2);获取的结果为:1线程A执行:this.compareAndSwapInt(var1,var2,var5,var5 var4),此时线程A使用var1和var2从AtomicInteger中获取的值为:1,而传入的var5为1,比较成功,将其修改为var5 var4,也就是2,将AtomicInteger中的值改为2,结束。
,