JUC---12深入理解CAS
一、什么是CAS
Compare and Swap, 翻译成比较并交换,是java.util.concurrent.atomic包下的类里面的CompareAndSet()方法;java.util.concurrent包中借助CAS实现了区别于synchronouse同步锁的一种乐观锁,使用这些类在多核CPU的机器上会有比较好的性能。
二、小例子
把2020交换为2021,之后获取操作后的值。再重复一次查看效果
public class MyDemo {
// CAS compareAndSet : 比较并交换!
public static void main(String[] args) {
AtomicInteger atomicInteger = new AtomicInteger(2020);
// 期望、更新
// public final boolean compareAndSet(int expect, int update)
// 如果我期望的值达到了,那么就更新,否则,就不更新, CAS 是CPU的并发原语!
System.out.println(atomicInteger.compareAndSet(2020, 2021));
System.out.println(atomicInteger.get());
atomicInteger.getAndIncrement();
System.out.println(atomicInteger.compareAndSet(2020, 2021));
System.out.println(atomicInteger.get());
}
}
在java.util.concurrent.atomic包下的任意类调用CompareAndSet()方法,都是调用Unsafe类里面的方法,这个类是底层的,Java调用C++操作。
在调用getAndIncrement()方法后,方法里面调用unsafe.getAndAddInt(this, valueOffset, 1);到Unsafe类里面操作public final int getAndAddInt(Object var1, long var2, int var4)
方法,其中【this---var1,valueOffset---var2,1---var4】,在这个方法里面,通过var5 = this.getIntVolatile(var1, var2);获取内存地址中的值,然后再调用this.compareAndSwapInt(var1, var2, var5, var5 + var4),使其为真。
缺点:
1、循环会耗时
2、一次性只能保证一个共享变量的原子性
3、ABA问题----就是多线程下,例如有3个线程同时对同一个值(初始值为A)进行CAS操作,其中两个线程:线程1,期望值为A,欲更新的值为B;线程2,期望值为A,欲更新的值为B。当线程1抢先获得CPU时间片,而线程2因为其他原因阻塞了,线程1取值与期望的A值比较,发现相等然后将值更新为B,然后这个时候出现了线程3,期望值为B,欲更新的值为A,线程3取值与期望的值B比较,发现相等则将值更新为A,此时线程2从阻塞中恢复,并且获得了CPU时间片,这时候线程2取值与期望的值A比较,发现相等则将值更新为B,虽然线程2也完成了操作,但是线程2并不知道值已经经过了A->B->A的变化过程。
+1,即A->B->A就变成了1A->2B->3A。(这就是乐观锁的思想)public class MyDemo {
static AtomicStampedReference<Integer> atomicStampedReference = new AtomicStampedReference<>(1, 1);
// CAS compareAndSet : 比较并交换!
public static void main(String[] args) {
new Thread(() -> {
int stamp = atomicStampedReference.getStamp(); // 获得版本号
System.out.println("a1=>" + stamp);
try {
TimeUnit.SECONDS.sleep(1);
} catch (InterruptedException e) {
e.printStackTrace();
}
atomicStampedReference.compareAndSet(1, 2,
atomicStampedReference.getStamp(),
atomicStampedReference.getStamp() + 1);
System.out.println("a2=>" + atomicStampedReference.getStamp());
System.out.println(atomicStampedReference.compareAndSet(2, 1,
atomicStampedReference.getStamp(),
atomicStampedReference.getStamp() + 1));
System.out.println("a3=>" + atomicStampedReference.getStamp());
}, "a").start();
// 乐观锁的原理相同!
new Thread(() -> {
int stamp = atomicStampedReference.getStamp(); // 获得版本号
System.out.println("b1=>" + stamp);
try {
TimeUnit.SECONDS.sleep(2);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(atomicStampedReference.compareAndSet(1, 6,
stamp, stamp + 1));
System.out.println("b2=>" + atomicStampedReference.getStamp());
}, "b").start();
}
}
JUC---12深入理解CAS的更多相关文章
- (白话理解)CAS机制
(白话理解)CAS机制 通过一段对话我们来了解cas用意 示例程序:启动两个线程,每个线程中让静态变量count循环累加100次. 最终输出的count结果是什么呢?一定会是200吗? 加了同步锁之后 ...
- 【Java】手把手理解CAS实现原理
先来看看概念,[CAS] 全称“CompareAndSwap”,中文翻译即“比较并替换”. 定义:CAS操作包含三个操作数 —— 内存位置(V),期望值(A),和新值(B). 如果内存位置的值与期望值 ...
- JUC(10)深入理解CAS和ABA
文章目录 1.CAS 2.原子引用解决ABA问题,版本号.修改后,可以看到 1.CAS package com.cas; import java.util.concurrent.atomic.Atom ...
- SQL Server代理(5/12):理解SQL代理错误日志
SQL Server代理是所有实时数据库的核心.代理有很多不明显的用法,因此系统的知识,对于开发人员还是DBA都是有用的.这系列文章会通俗介绍它的很多用法. 如我们在这个系列的前几篇文章所见,SQL ...
- http://python.jobbole.com/85056/ 简单 12 步理解 Python 装饰器,https://www.cnblogs.com/deeper/p/7482958.html另一篇文章
好吧,我标题党了.作为 Python 教师,我发现理解装饰器是学生们从接触后就一直纠结的问题.那是因为装饰器确实难以理解!想弄明白装饰器,需要理解一些函数式编程概念,并且要对Python中函数定义和函 ...
- SQL Server代理(9/12):理解作业和安全
SQL Server代理是所有实时数据库的核心.代理有很多不明显的用法,因此系统的知识,对于开发人员还是DBA都是有用的.这系列文章会通俗介绍它的很多用法. 在这个系列的前一篇文章里,你学习了如何在S ...
- 理解cas
前言 CAS(Compare and Swap),即比较并替换,实现并发算法时常用到的一种技术,Doug lea大神在java同步器中大量使用了CAS技术,鬼斧神工的实现了多线程执行的安全性. CAS ...
- 12深入理解C指针之---指针多层间接引用
该系列文章源于<深入理解C指针>的阅读与理解,由于本人的见识和知识的欠缺可能有误,还望大家批评指教. 一.指针多层引用 1.定义:指针可以用不同的间接引用层级,通常使用多重指针或字符数组来 ...
- 【Java】手把手模拟CAS,瞬间理解CAS的机制
话不多少,先看个案例,[模拟100个用户,每个用户访问10次网站]”: public class ThreadDemo1 { //总访问量 ; //模拟访问的方法 public static void ...
随机推荐
- 干货满满!关于Pycharm远程开发
可以在Windows中使用Pycharm编写代码,而代码的调试运行可以使用远程服务器中的python解释器. 在本地创建好工程项目(或从git上clone下代码)后,用Pycharm打开: 打开「To ...
- 全世界最强的算法平台codeforces究竟有什么魅力?
大家好,之前说过由于和LeetCode结了梁子,所以周末的LeetCode专题取消了,给大家写点其他专题的算法问题.目前选择的是国外著名的编程竞赛平台--codeforces.它在竞赛圈名气比较大,对 ...
- Unity Shader学习笔记-1
本篇文章是对Unity Shader入门精要的学习笔记,插图大部分来自冯乐乐女神的github 如果有什么说的不正确的请批评指正 目录 渲染流水线 流程图 Shader作用 屏幕映射 三角形遍历 两大 ...
- 和低效 IO 说再见,回头补一波 Java 7 的 NIO.2 特性
其实在这之前已经写过一篇关于 Java 7 的新特性文章了,那篇文章主要介绍了 Java 7 的资源自动关闭.Switch String 实现原理.异常捕获 try-catch.新的二进制书写方式等, ...
- 动态生成简约MVC请求接口|抛弃一切注解减少重复劳动吧
背景 目前创建一个后端请求接口给别人提供服务,无论是使用SpringMVC方式注解,还是使用SpringCloud的Feign注解,都是需要填写好@RequestMap.@Controller.@Pa ...
- Python 3 入门,看这篇就够了(超全整理)
史上最全Python资料汇总(长期更新).隔壁小孩都馋哭了 --- 点击领取 今天和大家分享的内容是Python入门干货,文章很长. 简介 Python 是一种高层次的结合了解释性.编译性.互动性和面 ...
- 计算(calc)
计算(calc) [题目描述] 小明在你的帮助下,破密了Ferrari设的密码门,正要往前走,突然又出现了一个密码门,门上有一个算式,其中只有"(",")",& ...
- matlab中colormap
来源:https://ww2.mathworks.cn/help/matlab/ref/colormap.html?searchHighlight=colormap&s_tid=doc_src ...
- java进阶(26)--ForEach
JDK5.0后新特性 一.普通for循环
- jquery购物车全选,取消全选,计算总金额
这是html代码 <div class="gwcxqbj"> <div class="gwcxd center"> <div cl ...