JUC(10)深入理解CAS和ABA
1、CAS


package com.cas;
import java.util.concurrent.atomic.AtomicInteger;
/**
* CAS compareAndSet:比较并交换
*/
public class CASDemo {
public static void main(String[] args) {
AtomicInteger atomicInteger = new AtomicInteger(2021);
/**
* 期望、更新
* public final boolean compareAndSet(int expect, int update)
* 如果期望值达到了,那么就更新,否则,就不更新
*/
atomicInteger.compareAndSet(2021,2022);
System.out.println(atomicInteger.get());
}
}
CAS:比较当前工作内存中的值和主存中的值,如果这个值是期望的,那么执行操作!如果不是、一直循环
缺点:
- 1、循环会耗时
- 2、一次性只能保证一个共享变量的原子性
- 3、存在ABA问题
ABA问题:狸猫换太子
举例子:A 打算让1变为2.在这个过程中,线程B已经对其进行过修改,从1,到3,再从3,到1。对线程A来讲,好像没啥大的变化。

package com.cas;
import java.util.concurrent.atomic.AtomicInteger;
public class ABADemo {
public static void main(String[] args) {
AtomicInteger atomicInteger = new AtomicInteger(2021);
/**
* 期望、更新
* public final boolean compareAndSet(int expect, int update)
* 如果期望值达到了,那么就更新,否则,就不更新
*/
System.out.println(atomicInteger.compareAndSet(2021, 2022));
System.out.println(atomicInteger.get());
System.out.println(atomicInteger.compareAndSet(2022, 2021));
System.out.println(atomicInteger.get());
System.out.println(atomicInteger.compareAndSet(2021, 6666));
System.out.println(atomicInteger.get());
}
}
2、原子引用解决ABA问题,版本号。修改后,可以看到





举例子(乐观锁)
package com.cas;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicStampedReference;
/**
* AtomicStampedReference 注意:如果泛型是一个包装类,注意对象的引用问题
*/
public class AtomicStampedReferenceDemo {
public static void main(String[] args) {
AtomicStampedReference<Integer> atomicStampedReference = new AtomicStampedReference<>(66, 1);
new Thread(()->{
int stamp = atomicStampedReference.getStamp();//获得版本号
System.out.println("A===>"+stamp);
atomicStampedReference.compareAndSet(66,99,atomicStampedReference.getStamp(),atomicStampedReference.getStamp()+1);
System.out.println("A2==>"+atomicStampedReference.getStamp());
atomicStampedReference.compareAndSet(99,66,atomicStampedReference.getStamp(),atomicStampedReference.getStamp()+1);
System.out.println("A3==>"+atomicStampedReference.getStamp());
},"A").start();
new Thread(()->{
int stamp = atomicStampedReference.getStamp();//获得版本号
System.out.println("B===>"+stamp);
try {
TimeUnit.SECONDS.sleep(6);
} catch (InterruptedException e) {
e.printStackTrace();
}
atomicStampedReference.compareAndSet(66,6,stamp,stamp+1);
System.out.println("B1==>"+atomicStampedReference.getStamp());
},"B").start();
}
}
测试结果

JUC(10)深入理解CAS和ABA的更多相关文章
- java并发编程(十三)----(JUC原子类)引用类型介绍(CAS和ABA的介绍)
这一节我们将探讨引用类型原子类:AtomicReference, AtomicStampedRerence, AtomicMarkableReference.AtomicReference的使用非常简 ...
- Java高性能编程之CAS与ABA及解决方法
Java高性能编程之CAS与ABA及解决方法 前言 如果喜欢暗色调的界面或者想换换界面,可以看看我在个人博客发布的 Java高性能编程之CAS与ABA及解决方法. CAS概念 CAS,全称Compar ...
- (白话理解)CAS机制
(白话理解)CAS机制 通过一段对话我们来了解cas用意 示例程序:启动两个线程,每个线程中让静态变量count循环累加100次. 最终输出的count结果是什么呢?一定会是200吗? 加了同步锁之后 ...
- Java并发编程入门与高并发面试(三):线程安全性-原子性-CAS(CAS的ABA问题)
摘要:本文介绍线程的安全性,原子性,java.lang.Number包下的类与CAS操作,synchronized锁,和原子性操作各方法间的对比. 线程安全性 线程安全? 线程安全性? 原子性 Ato ...
- 沉淀再出发:java中的CAS和ABA问题整理
沉淀再出发:java中的CAS和ABA问题整理 一.前言 在多并发程序设计之中,我们不得不面对并发.互斥.竞争.死锁.资源抢占等等问题,归根到底就是读写的问题,有了读写才有了增删改查,才有了所有的一切 ...
- CAS及其ABA问题
CAS.volatile是JUC包实现同步的基础.Synchronized下的偏向锁.轻量级锁的获取.释放,lock机制下锁的获取.释放,获取失败后线程的入队等操作都是CAS操作锁标志位.state. ...
- CAS 和 ABA 问题
CAS简介 CAS 全称是 compare and swap,是一种用于在多线程环境下实现同步功能的机制. CAS 它是一条CPU并发原语.操作包含三个操作数 -- 内存位置.预期数值和新值.CAS ...
- 【Java】手把手理解CAS实现原理
先来看看概念,[CAS] 全称“CompareAndSwap”,中文翻译即“比较并替换”. 定义:CAS操作包含三个操作数 —— 内存位置(V),期望值(A),和新值(B). 如果内存位置的值与期望值 ...
- 智能合约语言 Solidity 教程系列10 - 完全理解函数修改器
这是Solidity教程系列文章第10篇,带大家完全理解Solidity的函数修改器. Solidity系列完整的文章列表请查看分类-Solidity. 写在前面 Solidity 是以太坊智能合约编 ...
随机推荐
- 开源深度思考 - In Community We Trust
作者 | 黄东旭,PingCAP 联合创始人&CTO 出品 | CSDN(ID:CSDNnews) 业界一直流传着黄东旭的传说:小学三年级开始写代码,四五年级学习C语言,初中毕业时,已经能够用 ...
- Luogu3379 【模板】最近公共祖先(LCA) (倍增LCA)
蒟蒻又来复习模板了.还WA了两次 #include <iostream> #include <cstdio> #include <cstring> #include ...
- Ansible部署MySQL编译安装
环境: 系统:centos7 x3 master:192.168.220.133 slave1:192.168.220.136 slave2:192.168.220.137 前期准备: slave1( ...
- Web 前端实战:JQ 实现树形控件
前言 这是一篇个人练习 Web 前端各种常见的控件.组件的实战系列文章.本篇文章将介绍个人通过 JQuery + 无序列表 + CSS 动画完成一个简易的树形控件. 最终实现的效果是: 这样结构比较复 ...
- Excel 运算符(二):比较运算符
比较运算符用于对两个数据进行比较运算,其结果为 TRUE(真)或 FALSE(假). 运算符 含义 实例 结果 = 等于 =2=3 FALSE < 小于 =5<2 FALSE > 大 ...
- tqdm和zip组合使用时无法显示进度条-解决办法
问题 单独对于可迭代对象iterator使用tqdm时,结合循环就可以在终端显示进度条, 以直观展示程序进度,如下: from tqdm import tqdm textlist = [] for i ...
- JZOJ3542冒泡排序
题面 下面是一段实现冒泡排序算法的C++代码: for (int i=1;i<=n-1;i++) for (int j=1;j<=n-i ;j++) if(a[j]>a[j+1] ...
- 【java】学习路线4-对象、嵌套引用、匿名对象
class Learn03_MyClass{ String name = "www.pornhub.com";//成员变量:属性 public void Hello() ...
- centOS7.x修改root密码
方法一: 在开机的时候选中这一行(注意光标要进入虚拟机),然后按下e键 然后找到这一行(linux 16开头的)其中的ro,将其改为 rw init=sysroot/bin/sh 按ctrl+x执行 ...
- iOS 组件化及二进制化的探索
组件化的优缺点 组件化的拆分 组件与组件之间如何进行通讯(路由) 从Cocopods拉取代码的过程 远程索引库里很多的.spec文件,该文件记录了很多内容,如用户名,框架名称,描述,框架的地址 Pod ...