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属于乐观锁 悲观锁在高并发的场景下,激烈的锁竞争会造成线程阻塞,而大量阻塞 ...
随机推荐
- LSI SAS3IRCU配置SAS3系列RAID卡
LSI SAS3IRCU配置SAS3系列RAID卡 一.适用的controller LSISAS3008 LSISAS3004 二.名词解释 Controller: IR: Volume: 卷,基于物 ...
- Selenium API(二)
1.定位一组元素 WebDriver提供了8种定位一组元素的方法. driver.find_elements_by_css_selector() driver.find_elements_by_tag ...
- MongDB集群部署
http://blog.csdn.net/luonanqin/article/details/8497860 参数解释: dbpath:数据存放目录 logpath:日志存放路径 pidfilepat ...
- win10+anaconda环境下pyqt5+qt tools+eric6.18安装及汉化过程
最近需要用python编写一个小程序的界面,选择了pyqt5+eric6的配套组合,安装过程中遇到一些坑,特此记录.参考书籍是电子工业出版社的<PyQt5快速开发与实战>. 因为我使用an ...
- 三种timer控件的简单实例
.system.windows.forms .system.threading.timer .system.timers.timer using System; using System.Collec ...
- Android 开发环境的构建备忘
准备工作:下载Eclipse.JDK.Android SDK.ADT插件 下载地址:Eclipse:http://www.eclipse.org/downloads/ JD ...
- RUCM简介
一.动机 UCM:用例建模,主要用于结构化和文档需求方面. UCSs:用例规格说明书,通常是文本文档,所以描述中不可避免含有歧义. RUCM:限制性用例建模.目标 G1.使UCMs更加可理解并且更精确 ...
- 字符串变dict
1.eval 2.json # NameError: name # 'null' is not defined # i_dict=eval(i) 这种方式,如果dict字符串中有null ,将不能变成 ...
- Rails应用系列(1):初识Rails
第一个Rails应用 Rails是一个"模型-视图-控制器"框架(MVC).是用Ruby写的,所以要对Ruby要有一定的了解才能对rails框架深入学习.其实Ruby与Rails就 ...
- Python循环流程
1.for循环 计算1+2+3+……+100的和 count = 0 i = 1 for i in range(101): count+=i print(count) 前n项和公式为:Sn=n*a1+ ...