3.CAS原子操作
什么是原子性操作,按照官方的解析:原子操作不能在一个中间操作中停止,要么全部成功要么全部失败。(An atomic action cannot stop in the middle: it either happens completely, or it doesn't happen at all. No side effects of an atomic action are visible until the action is complete.),
-- 除了long和double的读写,其他的引用变量的读写操作都是原子性的
-- 如果加了volatile关键字,所有的引用变量的读写操作都是原子性的。
-- 原子操作不会被其他的线程干扰。但是会存在内存不一致(consistency memory)的问题。但是使用关键字volatile可以大大减少这个风险。
-- 线程修改volatile变量的时候,会在这个变量上面和其他的读取该变量的读线程上面建立一个happens-before的关系。保证写线程对该变量的修改对其他的读线程是可见的。
compare and swap.在一个内存地址V,一个期望值A,一个新值B。如果在V上面是期望的A值,那么用B值去替换。否则通过自旋方式(死循环)一直到找到期望值位置。
3.1 为什么要有CAS,传统的锁有什么弊端
传统的锁实现比较笨重,如果程序中需要对某些计算变量实现原子性,是用java的锁会很笨重。而且给资源加锁如果控制不得当的话,容易出现死锁的现象。而CAS的出现就是为了解决在无锁的情况下也可以实现对于
资源的原子操作。
3.2 CAS的问题
+ CAS容易产生ABA问题,就是一个内存地址V,值是A。有一个a线程要去修改它的值,此时有一个b线程把A的值改为了B,然后再改回A,此时对于a线程来说,它对于b线程的修改操作时无感知的。为了解决ABA问题,引入了版本号。所有
线程修改一个内存的值前要先获取值的版本号,修改完后需要更新版本号。这似乎就需要使用AtomicStampedReference来操作了。如果是不关心值是否被修改过的情况,不需要考虑ABA问题。
+ 因为CAS会以自旋的方式索引期望值,如果一直没有索引到期望值。为了防止一直自旋下去,cpu会设置一定的阈值,超过阈值后就会挂起这个线程,让出cpu。
3.3 举例
/**
* 演示带版本Stamp的AtomicStampedReference使用
* compareAndSet方法,需要指定老的版本号,如果设置成功返回true,否则返回false
* @author 45027056
*
*/
public class UseAtomicReferenceWithStamp {
static String name = "luke";
AtomicStampedReference atomicStampedReference = new AtomicStampedReference(name,0);
public static void main(String[] args) {
UseAtomicReferenceWithStamp demo = new UseAtomicReferenceWithStamp();
demo.new SuccessThread().start();
de mo.new FailThread().start();
System.out.println("local name is...:"+ name);
}
class SuccessThread extends Thread{
int oldStamp = atomicStampedReference.getStamp();
String oldReferenct = (String) atomicStampedReference.getReference();
@Override
public void run() {
boolean result = atomicStampedReference.compareAndSet(oldReferenct, "joe1", 0, 1);
System.out.println("refernce is :" + atomicStampedReference.getReference());
System.out.println("stamp is :" + atomicStampedReference.getStamp());
System.out.println("result is :" + result);
}
}
class FailThread extends Thread{
int oldStamp = atomicStampedReference.getStamp();
String oldReferenct = (String) atomicStampedReference.getReference();
@Override
public void run() {
boolean result = atomicStampedReference.compareAndSet(oldReferenct, "joe2", 0, 1);
System.out.println("refernce is" + atomicStampedReference.getReference());
System.out.println("stamp is" + atomicStampedReference.getStamp());
System.out.println("result is :" + result);
}
}
}
3.CAS原子操作的更多相关文章
- CAS原子操作实现无锁及性能分析
CAS原子操作实现无锁及性能分析 Author:Echo Chen(陈斌) Email:chenb19870707@gmail.com Blog:Blog.csdn.net/chen19870707 ...
- CAS 原子操作
理会CAS和CAS: 有时候面试官面试问你的时候,会问,谈谈你对CAS的理解,这时应该有很多人,就会比较懵,当然,我也会比较懵,当然我和很多人的懵不同,很多人可能,并不知道CAS是一个什么东西,而在我 ...
- 原子操作cas
一.概念, 基于处理器指令,把比较和交换合成一个指令完成,保证了原子性: 因为是针对一个内存地址值的,一个内存地址指向一个变量,所以只对一个共享变量能保证原子性: 二.原子操作类 锁只有synchro ...
- 锁&锁与指令原子操作的关系 & cas_Queue
锁 锁以及信号量对大部分人来说都是非常熟悉的,特别是常用的mutex.锁有很多种,互斥锁,自旋锁,读写锁,顺序锁,等等,这里就只介绍常见到的, 互斥锁 这个是最常用的,win32:CreateMute ...
- Java锁与CAS
一.加锁与无锁CAS 在谈论无锁概念时,总会关联起乐观派与悲观派,对于乐观派而言,他们认为事情总会往好的方向发展,总是认为坏的情况发生的概率特别小,可以无所顾忌地做事,但对于悲观派而已,他们总会认为发 ...
- 转:Java中的cas
引自:https://blog.csdn.net/mmoren/article/details/79185862 本篇的思路是先阐明无锁执行者CAS的核心算法原理然后分析Java执行CAS的实践者Un ...
- java并发编程(十三)----(JUC原子类)引用类型介绍(CAS和ABA的介绍)
这一节我们将探讨引用类型原子类:AtomicReference, AtomicStampedRerence, AtomicMarkableReference.AtomicReference的使用非常简 ...
- 基于 CAS 无锁实现的 Disruptor.NET 居然慢于 BlockingCollection,是真的吗?
StackOverflow 有人说自己的Disruptor.NET 代码比 BlockingCollection 还有慢 2 倍,并且把完整代码贴出,楼下几个老外也的回复说了一堆,但是没研究出个所以然 ...
- Java性能 -- CAS乐观锁
synchronized / Lock / CAS synchronized和Lock实现的同步锁机制,都属于悲观锁,而CAS属于乐观锁 悲观锁在高并发的场景下,激烈的锁竞争会造成线程阻塞,而大量阻塞 ...
随机推荐
- App测试从入门到精通之App分类和场景操作系统
App概要 APP是application的缩写.通常指的是手机软件上的应用,或称为手机客户端.手机app就是手机的应用程序.随着智能手机的越发普及,用户越发依赖手机软件商品店,app开发的需求与发展 ...
- 如何确定tabcontrol哪一页码是活跃页???
tabControl1.SelectedIndex属性 显示了现在显示的是哪一页码内的控件.
- datebox 和 datetimebox 添加『清空』按钮
需要引入 easyui-lang-zh_CN.js $(document).ready(function(){ var d_buttons = $.extend([], $.fn.datebox.de ...
- 编写高质量代码改善C#程序的157个建议——建议29:区别LINQ查询中的IEnumerable<T>和IQueryable<T>
建议29:区别LINQ查询中的IEnumerable<T>和IQueryable<T> LINQ查询一共提供了两类扩展方法,在System.Linq命名空间下,有两个静态类:E ...
- 用JS实现省市二级联动
一.需求分析 我们希望在注册页面中添加一个字段(籍贯),当用户选择一个具体的省份,在后面的下拉列表中动态加载该省份下所有的城市.显示的效果如下: 二.技术分析 使用事件(onchange) 使用一个二 ...
- 解决dragsort鼠标拖动与onclick事件共存
- git vs sourcetree
SourceTree&Git部分名词解释 克隆(clone):从远程仓库URL加载创建一个与远程仓库一样的本地仓库 提交(commit):将暂存文件上传到本地仓库(我们在Finder中对本地仓 ...
- angular 模板表单
- 20165219 预备作业3 Linux安装及学习
20165219 预备作业3 Linux安装及学习 安装虚拟机 在安装的过程中遇到了不少的问题,在同学的帮助下都得到了解决.比如在新建虚拟机的时候没有64位这个选项,后来知道需要开启虚拟化,然后是安装 ...
- javascript正则表达式——元字符
元字符(Metacharacter)是拥有特殊含义的字符: 元字符 描述 (1) . 查找单个字符,除了换行和行结束符. 例子: <!DOCTYPE h ...