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 是以太坊智能合约编 ...
随机推荐
- 搞定面试官 - 你可以介绍一下在 MySQL 中,哪些情况下 索引会失效嘛?
大家好,我是程序员啊粥,前边给大家分享了 *MySQL InnoDB 索引模型 在 MySQL InnoDB 中,为什么 delete 删除数据之后表数据文件大小没有变 如何计算一个索引的长度 如何查 ...
- linux tcp 在timewait 状态下的报文处理
最近处理一个问题,我们nginx服务器作为透明代理,将核心网过来的用户上网请求代理到我们的cache服务器,如果cache服务器没有命中内容,则需要我们 作为客户端往源站请求内容,但用户对此一无所知, ...
- 【JDBC】学习路径3-密码登录&SQL注入攻击
最后再提醒一句,每次在测试JDBC程序的时候,一定要确保MySQL正在运行. 打开控制台(终端),输入mysql 如果没启动,则出现以下提示: Mac端启动MySQL数据库,需要在系统便好设置中启动. ...
- Java连接简单使用ElasticSearch
目录 1. 添加依赖 2. 代码,无账号密码 3. 代码,有账号密码,并且是https方式 4. 参考文章 1. 添加依赖 <!-- https://mvnrepository.com/arti ...
- liunx系统docker部署.net core3.1
此篇文章演示基本的基于docker部署.netcore服务,liunx系统腾讯云ubuntu,.net core版本3.1. 1.安装docker apt install docker.io 2.拉取 ...
- 第七章 完成kubernetes集群部署并验证
在其中一运算个节点上操作就行 创建nginx资源配置清单的yaml文件 [root@hdss7-21 ~]# vim /opt/kubernetes/conf/nginx-ds.yaml apiVer ...
- KingbaseES V8R3集群管理和维护案例之---failover切换wal日志变化分析
案例说明: 本案例通过对KingbaseES V8R3集群failover切换过程进行观察,分析了主备库切换后wal日志的变化,对应用者了解KingbaseES V8R3(R6) failover ...
- gem5 使用记录,对例子中helloobject的理解
gem5中有一个 hello的例子,不是hello world那个,在src/learning-gem5/part2里面,这是虽然是个简单的例子但包含的要素挺多挺全. 整个结构是src下面有一个hel ...
- kali2020.1修改root密码,以最高权限登录系统
普通用户权限登录系统 sodu su切换为root权限 passwd root 按提示输入密码 再次输入密码 更新密码 右上角点切换用户 root/xxxx 更改成功,下面公布操图片
- 8.第七篇 验证kube-apiserver及kubeconfig配置详解
文章转载自:https://mp.weixin.qq.com/s?__biz=MzI1MDgwNzQ1MQ==&mid=2247483818&idx=1&sn=7572b791 ...