java并发:CAS算法和ABA问题
CAS算法是硬件对于并发的支持,针对多处理器操作而设计的处理器中的一种特殊指令。
CAS用于管理对共享数据的并发访问。
java的并发包中,AQS、原子操作类等都是基于CAS实现的。
CAS 是一种 无锁的 非阻塞算法的 实现。
CAS(Compare-And-Swap),简单来说就是比较和替换。
比较和替换是使用一个期望值和一个变量的当前值进行比较,如果当前变量的值与我们期望的值相等,就使用一个新值替换当前变量的值。
比如说,想使用一台机器,先通过比较判断这台机器是否处于未占用状态,如果机器处于未占用状态,就将它设为使用状态。
CAS 包含了三个操作数:
需要读写的内存值: V,进行比较的预估值: A,拟写入的更新值: B。
当且仅当 V == A 时, V = B, 否则,将不做任何操作;
以下用同步锁synchronized模拟CAS 算法。
注意:真正的CAS算法是无锁的。
如下:
public class CasDemo {
public static void main(String[] args) {
final CompareAndSwap cas = new CompareAndSwap();
for(int i=0; i<10; i++){
// 创建10个线程,模拟多线程环境
new Thread(new Runnable(){
@Override
public void run(){
int expectedValue = cas.get();
boolean b = cas.compareAndSwap(expectedValue, (int)(Math.random()*5));
}
}).start();
}
}
static class CompareAndSwap{
private int value;
// 获取内存值
public synchronized int get() {
return value;
}
// 比较当前值和期望值,相同就替换。
public synchronized boolean compareAndSwap(int expectedValue,int newValue) {
//获取旧值
int oldValue=value;
if(oldValue==expectedValue) {
this.value=newValue;
System.out.println(Thread.currentThread().getName()+"比较当前值和期望值,结果一致,将其替换为新值。");
return true;
}
System.out.println(Thread.currentThread().getName()+"比较当前值和期望值,结果不一致,不替换为新值");
return false;
}
}
}
ABA问题:
尽管CAS看起来没问题,其实存在一个逻辑漏洞。
如果一个变量V初次读取时是A值,并且在赋值时检查到它仍然是A值,那么我们就能说它的值没有改变过吗?
如果在此期间,它的值曾经改成了B,后来又改回为A。那么CAS操作就会误以为它从来没有改变过。
这个称为CAS的“ABA”问题。
当然,在大部分情况下ABA问题并不会影响程序并发的正确性。如果需要解决ABA问题,可以改用传统的互斥同步。
java并发:CAS算法和ABA问题的更多相关文章
- Java多线程_CAS算法和ABA问题
CAS算法概述CAS是英文单词CompareAndSwap的缩写,中文意思是:比较并替换.CAS需要有3个操作数:内存地址V,旧的预期值A,即将要更新的目标值B. CAS指令执行时,当且仅当内存地址V ...
- Java并发——CAS
什么是CAS? CAS是Compare And Swap的简称.在Java中有很多实现,比如compareAndSwapObject()方法,或者compareAndSwapInt()方法等.多用在包 ...
- java并发编程(十三)----(JUC原子类)引用类型介绍(CAS和ABA的介绍)
这一节我们将探讨引用类型原子类:AtomicReference, AtomicStampedRerence, AtomicMarkableReference.AtomicReference的使用非常简 ...
- Java并发编程入门与高并发面试(三):线程安全性-原子性-CAS(CAS的ABA问题)
摘要:本文介绍线程的安全性,原子性,java.lang.Number包下的类与CAS操作,synchronized锁,和原子性操作各方法间的对比. 线程安全性 线程安全? 线程安全性? 原子性 Ato ...
- Java并发问题--乐观锁与悲观锁以及乐观锁的一种实现方式-CAS
首先介绍一些乐观锁与悲观锁: 悲观锁:总是假设最坏的情况,每次去拿数据的时候都认为别人会修改,所以每次在拿数据的时候都会上锁,这样别人想拿这个数据就会阻塞直到它拿到锁.传统的关系型数据库里边就用到了很 ...
- Java并发编程:什么是CAS?这回总算知道了
无锁的思想 众所周知,Java中对并发控制的最常见方法就是锁,锁能保证同一时刻只能有一个线程访问临界区的资源,从而实现线程安全.然而,锁虽然有效,但采用的是一种悲观的策略.它假设每一次对临界区资源的访 ...
- Java并发(十二):CAS Unsafe Atomic
一.Unsafe Java无法直接访问底层操作系统,而是通过本地(native)方法来访问.不过尽管如此,JVM还是开了一个后门,JDK中有一个类Unsafe,它提供了硬件级别的原子操作. 这个类尽管 ...
- Java 并发(一) --- CAS
CAS 原理 先来看看下面的代码是否可以输出预期的值.开启了两个线程,是否会输出200 呢 结果由于并发的原因,结果会小于或等于200 , 原因出现在 count++; 由于这一行代码存在三个操作: ...
- Java并发编程系列-(3) 原子操作与CAS
3. 原子操作与CAS 3.1 原子操作 所谓原子操作是指不会被线程调度机制打断的操作:这种操作一旦开始,就一直运行到结束,中间不会有任何context switch,也就是切换到另一个线程. 为了实 ...
随机推荐
- 转载-MyBatis学习总结
MyBatis学习总结(八)——Mybatis3.x与Spring4.x整合 孤傲苍狼 2015-02-07 00:09 阅读:89825 评论:54 MyBatis学习总结(七)——Myba ...
- shell 10流程控制
if 判断 if #shell #!/bin/sh a=5 if [[ $a > 3 ]];then echo "$a>3" fi #写成一行 if [[ $a < ...
- Linux-Zabbix
###############################安装######################################## 安装部分我写了文档,可能不是很完善 文档如下→→ [ ...
- SIP 认证方式
SIP认证是继承了HTTP的认证方式.HTTP的认证方案主要有Basic Authentication Scheme和Digest Access Authentication Scheme两种.而Ba ...
- javascript创建对象之原型模式(三)
少废话,先上代码: function Human() { } Human.prototype.name = "成吉思汗"; Human.prototype.sex = " ...
- Introducing Deep Reinforcement
The manuscript of Deep Reinforcement Learning is available now! It makes significant improvements to ...
- 深度学习RNN实现股票预测实战(附数据、代码)
背景知识 最近再看一些量化交易相关的材料,偶然在网上看到了一个关于用RNN实现股票预测的文章,出于好奇心把文章中介绍的代码在本地跑了一遍,发现可以work.于是就花了两个晚上的时间学习了下代码,顺便把 ...
- MySQL数据库索引(中)
上一篇回顾: 1.一个索引对应一颗B+树,所有的真实记录都是存在叶子节点里面的,所有的项目录都存在内节点或者说根节点上. 2.innodb会为我们的表格主键添加一个聚簇索引,如果没有主键的话数据库是会 ...
- openStack虚拟机error 错误状态基于差异镜像+基镜像做恢复
- VBA 判断单元格是否为公式,可用于数组
Function ISFORMULA(ByVal rg As Object) As Variant Dim temp As Variant Dim i As Integer, j ...