java并发编程(八) CAS & Unsafe & atomic
参考文档:
https://www.cnblogs.com/xrq730/p/4976007.html
CAS(Compare and Swap)
一个CAS方法包含三个参数CAS(V,E,N)。V表示要更新的变量,E表示预期的值,N表示新值。只有当V的值等于E时,才会将V的值修改为N。如果V的值不等于E,说明已经被其他线程修改了,当前线程可以放弃此操作,也可以再次尝试次操作直至修改成功。基于这样的算法,CAS操作即使没有锁,也可以发现其他线程对当前线程的干扰(临界区值的修改),并进行恰当的处理
CAS的实现原理
CAS是通过Unsafe实现的,看下Unsafe下的三个方法:
public final native boolean compareAndSwapObject(Object paramObject1, long paramLong, Object paramObject2, Object paramObject3);
public final native boolean compareAndSwapInt(Object paramObject, long paramLong, int paramInt1, int paramInt2);
public final native boolean compareAndSwapLong(Object paramObject, long paramLong1, long paramLong2, long paramLong3);
Java无法直接访问底层操作系统,而是通过本地(native)方法来访问。JDK中有一个类Unsafe,它提供了硬件级别的原子操作
这个类尽管里面的方法都是public的,但是并没有办法使用它们,JDK API文档也没有提供任何关于这个类的方法的解释。总而言之,对于Unsafe类的使用都是受限制的,只有授信的代码才能获得该类的实例,当然JDK库里面的类是可以随意使用的
CAS的应用
java.util.concurrent.atomic包下的原子操作类都是基于CAS实现的,下面拿AtomicInteger分析一下,首先是AtomicInteger类变量的定义:
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;
关于这段代码中出现的几个成员属性:
1、Unsafe是CAS的核心类
2、valueOffset表示的是变量值在内存中的偏移地址,因为Unsafe就是根据内存偏移地址获取数据的原值的
3、value是用volatile修饰的,这是非常关键的
举个栗子
public final int addAndGet(int delta) {
for (;;) {
int current = get();
int next = current + delta;
if (compareAndSet(current, next))
return next;
}
}
public final int get() {
return value;
}
CAS的缺点
CAS看起来很美,但这种操作显然无法涵盖并发下的所有场景,并且CAS从语义上来说也不是完美的,存在这样一个逻辑漏洞:如果一个变量V初次读取的时候是A值,并且在准备赋值的时候检查到它仍然是A值,那我们就能说明它的值没有被其他线程修改过了吗?如果在这段期间它的值曾经被改成了B,然后又改回A,那CAS操作就会误认为它从来没有被修改过。这个漏洞称为CAS操作的"ABA"问题。java.util.concurrent包为了解决这个问题,提供了一个带有标记的原子引用类"AtomicStampedReference",它可以通过控制变量值的版本来保证CAS的正确性。不过目前来说这个类比较"鸡肋",大部分情况下ABA问题并不会影响程序并发的正确性,如果需要解决ABA问题,使用传统的互斥同步可能回避原子类更加高效
java并发编程(八) CAS & Unsafe & atomic的更多相关文章
- Java并发编程笔记之Unsafe类和LockSupport类源码分析
一.Unsafe类的源码分析 JDK的rt.jar包中的Unsafe类提供了硬件级别的原子操作,Unsafe里面的方法都是native方法,通过使用JNI的方式来访问本地C++实现库. rt.jar ...
- Java并发编程 (八) J.U.C组件拓展
个人博客网:https://wushaopei.github.io/ (你想要这里多有) 一.J.U.C-FutureTask-1 FutureTask组件,该组件是JUC中的.但该组件不是 A ...
- Java并发(十二):CAS Unsafe Atomic
一.Unsafe Java无法直接访问底层操作系统,而是通过本地(native)方法来访问.不过尽管如此,JVM还是开了一个后门,JDK中有一个类Unsafe,它提供了硬件级别的原子操作. 这个类尽管 ...
- JAVA并发编程: CAS和AQS
版权声明:本文为博主原创文章,转载请注明出处 https://blog.csdn.net/u010862794/article/details/72892300 说起JAVA并发编程,就不得不聊 ...
- Java并发编程入门与高并发面试(三):线程安全性-原子性-CAS(CAS的ABA问题)
摘要:本文介绍线程的安全性,原子性,java.lang.Number包下的类与CAS操作,synchronized锁,和原子性操作各方法间的对比. 线程安全性 线程安全? 线程安全性? 原子性 Ato ...
- Java并发编程系列-(3) 原子操作与CAS
3. 原子操作与CAS 3.1 原子操作 所谓原子操作是指不会被线程调度机制打断的操作:这种操作一旦开始,就一直运行到结束,中间不会有任何context switch,也就是切换到另一个线程. 为了实 ...
- java并发编程笔记(八)——死锁
java并发编程笔记(八)--死锁 死锁发生的必要条件 互斥条件 进程对分配到的资源进行排他性的使用,即在一段时间内只能由一个进程使用,如果有其他进程在请求,只能等待. 请求和保持条件 进程已经保持了 ...
- java并发编程工具类JUC第八篇:ConcurrentHashMap
在之前的文章中已经为大家介绍了java并发编程的工具:BlockingQueue接口.ArrayBlockingQueue.DelayQueue.LinkedBlockingQueue.Priorit ...
- 转: 【Java并发编程】之十八:第五篇中volatile意外问题的正确分析解答(含代码)
转载请注明出处:http://blog.csdn.net/ns_code/article/details/17382679 在<Java并发编程学习笔记之五:volatile变量修饰符-意料之外 ...
随机推荐
- 2019 东方网java面试笔试题 (含面试题解析)
本人5年开发经验.18年年底开始跑路找工作,在互联网寒冬下成功拿到阿里巴巴.今日头条.东方网等公司offer,岗位是Java后端开发,因为发展原因最终选择去了东方网,入职一年时间了,也成为了面试官 ...
- "startIWDP": true
{ "platformName": "iOS", "platformVersion": "11.0", "au ...
- 编写可维护的JavaScript-随笔(二)
一.注释 1. 单行注释 a) 以两个斜线开始,以行位结束 b) 独占一行的注释,用来解释下一行的代码, c) 注释行之前总有一个空行 d) 缩进层级与下一行代 ...
- js学习之数据结构和算法
js中的数据结构 1.列表 待办事项列表.购物清单.最佳十名榜单等等. 适用: 1)数据结构较为简单, 2)不需要在一个长序列中查找元素,或者对其进行排序 2.栈 一摞盘子 ----- 添加删除只能从 ...
- WDA演练一:用户登陆界面设计(一)
一,新建用户表: 用户和密码参考标准的.这里给用户分了几个维度,以便后面进行接下来的业务设定. 二,新建ZLY_PORTAL 程序. 除了MAIN视图外,在添加LOGON视图. 1.导入预先做好的主页 ...
- Django 之 ContentType组件
一.什么是 ContentTypes ContentTypes 是 Django 内置的一个应用,它可以追踪记录项目中所有 app 和 model 的对应关系,并记录在 django_content_ ...
- 一款信息收集工具-theHarvester
用法: theHarvester -d 163.com -l 1000 -b baidutheHarvester -d 163.com -l 1000 -b google -d 后跟服务器域名 ...
- “IOS11不再信赖WOSIGN证书”公众号运营者如何应对
ptd->_thandle = (uintptr_t)(-1); {{}/*** 传入需要的参数,设置给*/{}给Fragment添加newInstance方法,将需要的参数传入,设置到bund ...
- 项目Beta冲刺(团队5/7)
项目Beta冲刺(团队) --5/7 作业要求: 项目Beta冲刺(团队) 1.团队信息 团队名 :男上加男 成员信息 : 队员学号 队员姓名 个人博客地址 备注 221600427 Alicesft ...
- MySQL 8.x 函数和操作符,官方网址:https://dev.mysql.com/doc/refman/8.0/en/functions.html
MySql 8.x 函数和操作符,官方网址:https://dev.mysql.com/doc/refman/8.0/en/functions.html