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的更多相关文章

  1. java并发编程(十三)----(JUC原子类)引用类型介绍(CAS和ABA的介绍)

    这一节我们将探讨引用类型原子类:AtomicReference, AtomicStampedRerence, AtomicMarkableReference.AtomicReference的使用非常简 ...

  2. Java高性能编程之CAS与ABA及解决方法

    Java高性能编程之CAS与ABA及解决方法 前言 如果喜欢暗色调的界面或者想换换界面,可以看看我在个人博客发布的 Java高性能编程之CAS与ABA及解决方法. CAS概念 CAS,全称Compar ...

  3. (白话理解)CAS机制

    (白话理解)CAS机制 通过一段对话我们来了解cas用意 示例程序:启动两个线程,每个线程中让静态变量count循环累加100次. 最终输出的count结果是什么呢?一定会是200吗? 加了同步锁之后 ...

  4. Java并发编程入门与高并发面试(三):线程安全性-原子性-CAS(CAS的ABA问题)

    摘要:本文介绍线程的安全性,原子性,java.lang.Number包下的类与CAS操作,synchronized锁,和原子性操作各方法间的对比. 线程安全性 线程安全? 线程安全性? 原子性 Ato ...

  5. 沉淀再出发:java中的CAS和ABA问题整理

    沉淀再出发:java中的CAS和ABA问题整理 一.前言 在多并发程序设计之中,我们不得不面对并发.互斥.竞争.死锁.资源抢占等等问题,归根到底就是读写的问题,有了读写才有了增删改查,才有了所有的一切 ...

  6. CAS及其ABA问题

    CAS.volatile是JUC包实现同步的基础.Synchronized下的偏向锁.轻量级锁的获取.释放,lock机制下锁的获取.释放,获取失败后线程的入队等操作都是CAS操作锁标志位.state. ...

  7. CAS 和 ABA 问题

    CAS简介 CAS 全称是 compare and swap,是一种用于在多线程环境下实现同步功能的机制. CAS 它是一条CPU并发原语.操作包含三个操作数 -- 内存位置.预期数值和新值.CAS ...

  8. 【Java】手把手理解CAS实现原理

    先来看看概念,[CAS] 全称“CompareAndSwap”,中文翻译即“比较并替换”. 定义:CAS操作包含三个操作数 —— 内存位置(V),期望值(A),和新值(B). 如果内存位置的值与期望值 ...

  9. 智能合约语言 Solidity 教程系列10 - 完全理解函数修改器

    这是Solidity教程系列文章第10篇,带大家完全理解Solidity的函数修改器. Solidity系列完整的文章列表请查看分类-Solidity. 写在前面 Solidity 是以太坊智能合约编 ...

随机推荐

  1. day20--Java集合03

    Java集合03 8.LinkedList 1)linkedList底层实现了双向链表和双端队列的特点 2)可以添加任意元素(元素可以重复),包括null 3)线程不安全,没有实现同步 LinkedL ...

  2. java学习第四天高级数组.day13

    正则表达式 冒泡排序 二分法查找 线性查找:从头找到尾,性能比较低. 二分法查找(折半查找):前提数组元素是有序的,性能非常优异. Arrays

  3. feign远程调用出错

    如果你传递的参数,比较复杂时,默认会采用POST的请求方式. 传递单个参数时,推荐使用@PathVariable,如果传递的单个参数比较多,这里也可以采用@RequestParam,Feign接口中不 ...

  4. XYX错误集

    (频数递减) # 数据范围:没开Long Long (*inf^2) # while 打成了 if ,if 打成了 while(*inf^2) # 换根DP:两个dfs调用错误 (*inf) # ZK ...

  5. 第一百篇:JS异步

    好家伙,打工人要打工,博客会更新的没有以前频繁了   芜湖,一百篇了,这篇写一个比较难的异步(其实并不难理解,主要是为promise铺垫)   老样子,先补点基础: 1.进程 来吧,新华字典    大 ...

  6. Knative部署应用以及应用的更新、应用的分流(二)

    1. 应用的更新 1.1 更新hello-example应用 1.更新应用的环境变量 可通过命令行的方式亦可以通过读取配置文件的方式,这里主要来看命令行的方式 [root@kn-server-mast ...

  7. 自定义View4-塔防小游戏第一篇:一个防御塔+多个野怪(简易版)*

    塔防小游戏 第一篇:一个防御塔+多个野怪(简易版)    1.canvas画防御塔,妖怪大道,妖怪行走路线    2.防御塔攻击范围是按照妖怪与防御塔中心距离计算的,大于防御塔半径则不攻击,小于则攻击 ...

  8. KingbaseES R6 集群sys_monitor.sh change_password一键修改集群用户密码

    案例说明: kingbaseES R6集群用户密码修改,需要修改两处: 1)修改数据库用户密码(alter user): 2)修改.encpwd文件中用户密码: 可以通过sys_monitor.sh ...

  9. NODE 基于express 框架和mongoDB的cookie和session认证 和图片的上传和删除

    源码地址 https://gitee.com/zyqwasd/mongdbSession 本项目的mongodb是本地的mongodb 开启方法可以百度一下 端口是默认的27017 页面效果 1. 注 ...

  10. 如何搭建安全的 CI/CD 管道?

    Eolink 前端负责人黎芷君进行了<工程化- CI / CD>的主题演讲,围绕 CI/CD 管道安全的实践,分享自己在搭建 CI/CD 管道过程中所总结的重要经验,与开发者深入讨论 &q ...