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. Python 爬取汽车之家口碑数据

    本文仅供学习交流使用,如侵立删!联系方式见文末 汽车之家口碑数据 2021.8.3 更新 增加用户信息参数.认证车辆信息等 2021.3.24 更新 更新最新数据接口 2020.12.25 更新 添加 ...

  2. 基于图像二维熵的视频信号丢失检测(Signal Loss Detection)

    1 图像二维熵 ​图像二维熵作为一种特征评价尺度能够反映出整个图像所含平均信息量的高低,熵值(H)越大则代表图像所包含的信息越多,反之熵值(H)越小,则图像包含的信息越少.对于图像信息量,可以简单地认 ...

  3. synchronized原理剖析

    synchronized原理剖析 并发编程存在什么问题? 1️⃣ 可见性 可见性:是指当一个线程对共享变量进行了修改,那么另外的线程可以立即看到修改后的最新值. 案例演示:一个线程A根据 boolea ...

  4. mybatis-plus 生成全套crud

    pom依赖: <!-- web依赖--> <dependency> <groupId>org.springframework.boot</groupId> ...

  5. zkw线段树——简单易懂好写好调的线段树

    0.简介 zkw线段树是一种非递归线段树,与普通线段树不同的是,它是棵标准的满二叉树,所以遍历过程可全程使用位运算,常数一般比线段树小得多. 1.结构/建树 前面说了,zkw线段树是满二叉树,可是原数 ...

  6. Windows批量修改文件

    如图我是建立了壁纸文件夹 Windows自带的排序方式 如何不用自带的呢? 在这个文件夹里面建一个.txt文件 如下 ok第二步骤 将UTF-8格式改为ANSI格式 点击文件-另存为ANSI格式-替换 ...

  7. 【漏洞分析】KaoyaSwap 安全事件分析

    相关信息 KaoyaSwap 是 BSC 链上的一个自动做市商 AMM.然后,现在他们的官网 https://www.kaoyaswap.com/ 已经打不开了(如果我打开方式没错的话).所以就直接进 ...

  8. 从零开始搭建react基础开发环境(基于webpack5)

    前言 最近利用闲暇时间把webpack系统的学习了下,搭建出一个react环境的脚手架,写篇文章总结一下,帮助正在学习webpack小伙伴们,如有写的不对的地方或还有可以优化的地方,望大佬们指出,及时 ...

  9. Java代码自动计算机

    答案(这里面包括main方法不要写重了),copy即可使用: public static void main(String[] args) { while (true){ System.out.pri ...

  10. 性能调优——小小的log大大的坑

    引言 "只有被线上服务问题毒打过的人才明白日志有多重要!" 我先说结论,谁赞成,谁反对?如果你深有同感,那恭喜你是个社会人了:) 日志对程序的重要性不言而喻,轻巧.简单.无需费脑, ...