CAS总结
n++的问题不能保证原子操作。 因为被编译后拆分成了3个指令,先获取值,然后加一,然后写回内存。
把变量声明为volatile,volatile只能保证内存可见性,但是不能保证原子性,在多线程并发下,无法保证线程安全。
三个参数,一个当前内存值V、旧的预期值A、即将更新的值B,当且仅当预期值A和内存值V相同时,将内存值修改为B并返回true,
否则什么都不做,并返回false。
CAS跟synchronized要达到的效果是一样的,保证同一个时刻只有一个线程可以操作成功。
只不过CAS是硬件级别上面的锁,会锁住总线,保证只有一个CPU可以访问内存,对于用户层面来说应该是乐观锁,synchronized是JVM级别的锁,开销比较大
分析一下 AtomicInteger,变量value存储的实际值,被volatile修饰,保证其值改变后,其他线程可以立马看见。
public class AtomicInteger extends Number implements java.io.Serializable {
// setup to use Unsafe.compareAndSwapInt for updates
private static final Unsafe unsafe = Unsafe.getUnsafe();
private static final long valueOffset;
static {
try {
valueOffset = unsafe.objectFieldOffset
(AtomicInteger.class.getDeclaredField("value"));
} catch (Exception ex) { throw new Error(ex); }
}
private volatile int value;
public final int get() {return value;}
}
public final int getAndAdd(int delta) {
return unsafe.getAndAddInt(this, valueOffset, delta);
}
// 并发累加操作
public final int getAndAddInt(Object var1, long var2, int var4) {
int var5;
do {
var5 = this.getIntVolatile(var1, var2);
} while(!this.compareAndSwapInt(var1, var2, var5, var5 + var4));
return var5;
}
假设线程A和线程B同时执行getAndAdd操作(分别跑在不同CPU上):
假设AtomicInteger里面的value原始值为3,即主内存中AtomicInteger的value为3,根据Java内存模型,线程A和线程B各自持有一份value的副本,值为3。
线程A通过getIntVolatile(var1, var2)拿到value值3,这时线程A被挂起。
线程B也通过getIntVolatile(var1, var2)方法获取到value值3,运气好,线程B没有被挂起,并执行compareAndSwapInt方法比较内存值也为3,成功修改内存值为2。
这时线程A恢复,执行compareAndSwapInt方法比较,发现自己手里的值(3)和内存的值(2)不一致,说明该值已经被其它线程提前修改过了,那只能重新来一遍了。
重新获取value值,因为变量value被volatile修饰,所以其它线程对它的修改,线程A总是能够看到,线程A继续执行compareAndSwapInt进行比较替换,直到成功。
在这里的一个前提是compareAndSwapInt总是能拿到内存的最新值,然后把自己手上的值跟内存最新值比较,如果相等,即符合预期,则更新,如果不一致,进行下一轮
循环,重新获取内存最新值。
底层是通过Unsafe这个类compareAndSwapInt进行比较替换,Unsafe类compareAndSwapInt这个是C++实现的,不同操作系统有不同的实现,它能直接操作的内存偏移地址,
拿到内存最新值,然后跟旧的值进行比较替换。它能在CPU级别实现锁的机制,保证原子性
大致原理就是
1.如果是多处理器,为cmpxchg指令添加lock前缀 ,单处理器,省略lock前缀。
单处理器实际上不存在多个线程同时并行操作的场景,因为只有一个cpu,操作都是串行的,CPU根据时间片轮询执行不同线程。
lock前缀可以保证后续执行指令的原子性,老的处理器的做法是锁住总线,开销很大,新的处理器使用缓存锁定。
参考:https://www.jianshu.com/p/24ffe531e9ee
CAS总结的更多相关文章
- .NET应用和AEAI CAS集成详解
1 概述 数通畅联某综合SOA集成项目的统一身份认证工作,需要第三方系统配合进行单点登录的配置改造,在项目中有需要进行单点登录配置的.NET应用系统,本文专门记录.NET应用和AEAI CAS的集成过 ...
- SuperMap-iServer-单点登录功能验证(CAS)
SuperMap-iServer-单点登录功能验证(CAS) 1.测试目的: 验证SuperMap-iServer使用CAS单点登录的功能是否正常. 2.测试环境: SuperMap-iServer8 ...
- 集成基于CAS协议的单点登陆
相信大家对单点登陆(SSO,Single Sign On)这个名词并不感到陌生吧?简单地说,单点登陆允许多个应用使用同一个登陆服务.一旦一个用户登陆了一个支持单点登陆的应用,那么在进入其它使用同一单点 ...
- 【Java并发编程实战】-----“J.U.C”:CAS操作
CAS,即Compare and Swap,中文翻译为"比较并交换". 对于JUC包中,CAS理论是实现整个java并发包的基石.从整体来看,concurrent包的实现示意图如下 ...
- 多线程同步工具——CAS原子变量
这是我参考的一篇文章<基于CAS的乐观锁实现>,讲述的是一种需要CPU支持的执行技术CAS(Compare and Swap). 首先理解什么是原子性操作,意思是不能再拆分的操作,例如改写 ...
- CAS FOR WINDOW ACTIVE DIRECTORY SSO单点登录
一.CAS是什么? CAS(Central Authentication Service)是 Yale 大学发起的一个企业级的.开源的项目,旨在为 Web 应用系统提供一种可靠的单点登录解决方法(支持 ...
- CAS Client集群环境的Session问题及解决方案
[原创申明:文章为原创,欢迎非盈利性转载,但转载必须注明来源] 之前写过一篇文章,介绍单点登录的基本原理.这篇文章重点介绍开源单点登录系统CAS的登录和注销的实现方法.并结合实际工作中碰到的问题,探讨 ...
- cas单点登录搭建
Cas Server下载:http://developer.jasig.org/cas/ Cas Client下载:http://developer.jasig.org/cas-clients/ 测试 ...
- CAS环境搭建
实验背景: 系统环境: Windows XP | SUN JDK1.6U4 | Tomcat6.0.14 | CAS Server 3.1.1 + CAS Client 2.1.1 主机完整名称: ...
- ovirt配置为cas登录
准备工作 Ovirt测试机.CAS服务器.AD服务器 cas.crt -- CAS服务器的CA证书 allwinner.cer -- CAS服务器的证书颁发机构根证书 Ovirt测试机要求:apach ...
随机推荐
- Excel 常用快捷键
Excel 常用快捷键 1. 移动整列 使用Shift快捷键可以快速移动整列:选中该列,当鼠标变成十字箭头时,按住Shift键,然后将该列移动到想要的位置. 2 绝对引用 使用F4快捷键可以快速设置绝 ...
- 【转】ConcurrentMap 分析和思考
预备知识:Java HashMap and HashSet 的实现机制 由预备知识可以知道hashmap 的存储结构为: (图像来自http://www.ibm.com/developerworks/ ...
- CodeForces 146E Lucky Subsequence(组合数+DP)
题目描述 Petya loves lucky numbers very much. Everybody knows that lucky numbers are positive integers w ...
- Android-Application来传递数据
在上一篇博客中介绍到,Android-Intent意图传递数据,能够传递基本数据类型系列,能够传递对象(需要序列化),等操作: 但是如果要传递 List<T>,这种类型的数据,就不能通过I ...
- mongodb 搭建集群(分片+副本集)
mongodb 搭建集群(分片+副本集) 一.搭建结构图: 二.搭建步骤:
- MongoDB基础知识记录
MongoDB基础知识记录 一.概念: 讲mongdb就必须提一下nosql,因为mongdb是nosql的代表作: NoSQL(Not Only SQL ),意即“不仅仅是SQL” ,指的是非关系型 ...
- 使用adb工具调试出现error:device offline
使用adb工具调试设备的时候会出现error:device offline,网上找了很多办法,最后终于解决了. 如果你也遇到这样的问题,先试试简单的办法,不行的话,试试这个..<.< ad ...
- 2.css的引入方式
网页中引用CSS样式 内联样式 行内样式表 外部样式表 ..链接式 ..导入式 内嵌方式 style标签 <!doctype html> <html> <head> ...
- 面向对象中的__slots__
类中的__slots__ 正常情况下,当我们定义了一个class,创建了一个class的实例后,我们可以给该实例绑定任何属性和方法,这就是动态语言的灵活性. 而要限制class的属性就需要用到__sl ...
- Linux下简易进度条的实现
在生活中,进度条是很常见的,那么,进度条是如何实现的呢? 首先,进度条的动态是利用人眼视觉暂留效果的.实际上是如下过程: 先输出:[= ...