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属于乐观锁 悲观锁在高并发的场景下,激烈的锁竞争会造成线程阻塞,而大量阻塞 ...
随机推荐
- mysql 全文搜索 FULLTEXT
到 3.23.23 时,MySQL 开始支持全文索引和搜索.全文索引在 MySQL 中是一个 FULLTEXT 类型索引.FULLTEXT 索引用于 MyISAM 表,可以在 CREATE TABLE ...
- c#读取数据库内容
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.T ...
- netty使用以及聊天小程序
<从零开始搭建游戏服务器>Netty导入创建Socket服务器 Netty入门教程 Netty 聊天小程序
- C#ADO.NET基础一
简介 使用SQLite进行讲解 1.基础类: SQLiteConnection 连接数据库 SQLiteCommand 执行命令(增,删,改,查),或存储过程 SQLiteDataReader 读取查 ...
- C#NPOI.RabbitMQ.EF.Attribute.HttpRuntime.Cache.AD域.List<T>根据指定字段去重.前端JQuery.Cache.I18N(多语言).data-xx(自定义属性)
使用NPOI 操作Excel 个人使用的电脑基本默认安装Excel 操作起来 调用Excel的组件便可.如果是一台服务器.没有安装Excel,也就无法调用Excel组件. 在此推荐第三方插件.NPOI ...
- 基于任务的异步编程模式(TAP)
异步编程是C#5.0的一个重要改进,提供两个关键字:async和await.使用异步编程,方法的调用是在后台运行(通常在线程或任务的帮助下),但不会阻塞调用线程.异步模式分为3种:异步模式.基于事件的 ...
- 以太坊系列之十一: 零起步使用remix开发智能合约
一步一步使用remix开发智能合约 最新版的remix(2017-8-3)只能使用在线开发了,已经没有离线版本了,并且好像在线版本要FQ才能访问(自行解决). 1.打开remix 注意地址如果是htt ...
- linux上使用tomcat及查看日志
启动 startup.sh #执行bin/startup.sh #启动tomcatbin/shutdown.sh #停止tomcattail -f logs/catalina.out #看tomcat ...
- 洛谷P4525 【模板】自适应辛普森法1
题面 传送门 题解 我似乎连积分都不太熟练→_→ 总之就是对于一个原函数,我们找一个二次函数来近似它,那么有 \[ \begin{aligned} \int_a^bf(x)dx &\appro ...
- vmware vSphere虚拟网络之标准交换机(二)
一.标准交换机的特点: 1)只能用于物理主机 2)其他主机不能共享同一个虚拟交换机 3)不具备任何灵活性 4)每台ESXi主机都要配置一遍 二.网络图: 三.创建标准交换机: 登录web vCente ...