• CAS和多线程密切相关的东西!


    compare  and  swap:寄存器A的值和内存M的值进行比较,如果值相同,就把寄存器B和M的值进行交换

    更多的时候,不关心寄存器中的数量是啥,更关心内存的数值(变量的值)

    CAS相当于是把开了新世界的大门,让咱们不加锁就能保证线程安全!!
    基于CAS可以实现很多操作:

    • 实现原子类:标准库里提供了AtomInteger类,能够保证++,--的时候线程安全!

    基于CAS实现两个线程各自自增5W次

    1. import java.util.concurrent.atomic.AtomicInteger;
    2. public class Main1 {
    3. //基于CAS实现两个线程各自自增5W次
    4. public static void main(String[] args) throws InterruptedException{
    5. AtomicInteger num=new AtomicInteger(0);
    6. //初始化为0
    7. //线程1
    8. Thread t1=new Thread(()->{
    9. for (int i = 0; i < 50000; i++) {
    10. //num++ 后置++
    11. num.getAndIncrement();
    12. //++num 前置++
    13. //num.incrementAndGet();前置--
    14. // num.getAndDecrement();后置--
    15. }
    16. });
    17. //线程2
    18. Thread t2=new Thread(()->{
    19. for (int i = 0; i < 50000; i++) {
    20. num.getAndIncrement();
    21. //后置++
    22. }
    23. });
    24. t1.start();
    25. t2.start();
    26. //阻塞等待
    27. t1.join();
    28. t2.join();
    29. //get获取到数值
    30. System.out.println(num.get());//100000
    31. }
    32. }

    上述代码的运行结果为:

    • 实现自旋锁

    反复检查当前的锁状态,看是否解开了

    实现自旋目的就是为了忙等,就是为了能够最快速的拿到锁!!

    CAS还能做其他的很多事,在此便不再展开!!

    CAS的aba问题:面试中的经典问题!!

    CAS关键是对比内存和寄存器的值,看看是否相同(就是通过这个对比来检测内存是否变过),万一对比的时候是相同的,但是不是没变过,而是a->b->a??此时有一定的概率会出现!!

    CAS只能对比值是否相同,不能确定这个值是否中间发生过变化!!(这个事情大部分情况下都没事,但是小部分情况下会出现Bug!!)

    如何解决aba问题??

    aba关键是值反复横跳(a->b->a),如果约定数据只能单方向变化,那么,问题就迎刃而解了!!(只能增加/只能减少)

    但是若需求要求某数值,既能增加又能减少,咋办??

    可以引入另外一个版本号变量,约定版本号只能增加(每次修改,都会增加一个版本号)

    只要约定版本号,只能递增,就能保持此时不会出现aba反复横跳问题!!以版本号为基准,而不是变量数量为基准了!!

  • 相关阅读:
    对比学习损失篇,从L-softmax到AM-softmax到circle-loss到PCCL
    【SCAU数据挖掘】数据挖掘期末总复习题库简答题及解析——上
    UiPath实战(08) - 选取器(Selector)
    Spring学习笔记(三十七)——Flyway 数据库版本控制
    SpringBoot3.0——踩坑
    Vue-条件渲染和循环渲染
    探索请求头中的UUID的不同版本:UUID1、UUID3、UUID4和UUID5
    Java Map
    保姆级教程:个人深度学习工作站配置指南
    JavaScriptJQuery_jQuery简介
  • 原文地址:https://blog.csdn.net/weixin_64308540/article/details/132868637