zoukankan      html  css  js  c++  java
  • java并发:CAS算法和ABA问题

    CAS算法是硬件对于并发的支持,针对多处理器操作而设计的处理器中的一种特殊指令。

    CAS用于管理对共享数据的并发访问。

    java的并发包中,AQS、原子操作类等都是基于CAS实现的。

    CAS 是一种 无锁的 非阻塞算法的 实现。

    CAS(Compare-And-Swap),简单来说就是比较和替换。

    比较和替换是使用一个期望值和一个变量的当前值进行比较,如果当前变量的值与我们期望的值相等,就使用一个新值替换当前变量的值。

    比如说,想使用一台机器,先通过比较判断这台机器是否处于未占用状态,如果机器处于未占用状态,就将它设为使用状态。


    CAS 包含了三个操作数:
    需要读写的内存值: V,进行比较的预估值: A,拟写入的更新值: B。
    当且仅当 V == A 时, V = B, 否则,将不做任何操作;

    以下用同步锁synchronized模拟CAS 算法。

    注意:真正的CAS算法是无锁的。

    如下:

    public class CasDemo {
        public static void main(String[] args) {
            final CompareAndSwap cas = new CompareAndSwap();
    
            for(int i=0; i<10; i++){
                // 创建10个线程,模拟多线程环境
                new Thread(new Runnable(){
                    @Override
                    public void run(){
                        int expectedValue = cas.get();
    
                        boolean b = cas.compareAndSwap(expectedValue, (int)(Math.random()*5));
                    }
                }).start();
            }
        }
    
    
        static   class  CompareAndSwap{
             private  int value;
    
            // 获取内存值
             public synchronized  int get() {
                 return  value;
             }
    
             // 比较当前值和期望值,相同就替换。
             public  synchronized  boolean compareAndSwap(int expectedValue,int newValue) {
                 //获取旧值
                 int oldValue=value;
                 if(oldValue==expectedValue) {
                        this.value=newValue;
                        System.out.println(Thread.currentThread().getName()+"比较当前值和期望值,结果一致,将其替换为新值。");
                        return true;
                 }
                 System.out.println(Thread.currentThread().getName()+"比较当前值和期望值,结果不一致,不替换为新值");
                 return  false;
             }
        }
    }

    ABA问题:

    尽管CAS看起来没问题,其实存在一个逻辑漏洞。

    如果一个变量V初次读取时是A值,并且在赋值时检查到它仍然是A值,那么我们就能说它的值没有改变过吗?

    如果在此期间,它的值曾经改成了B,后来又改回为A。那么CAS操作就会误以为它从来没有改变过。

    这个称为CAS的“ABA”问题。

    当然,在大部分情况下ABA问题并不会影响程序并发的正确性。如果需要解决ABA问题,可以改用传统的互斥同步。

  • 相关阅读:
    io学习
    asp.net文件上传进度条研究
    asp.net页面中的Console.WriteLine结果如何查看
    谨慎跟随初始目的不被关联问题带偏
    android 按钮特效 波纹 Android button effects ripple
    安卓工作室 日志设置
    安卓工作室 文件浏览器 android studio File browser
    一个新的Android Studio 2.3.3可以在稳定的频道中使用。A new Android Studio 2.3.3 is available in the stable channel.
    新巴巴运动网上商城 项目 快速搭建 教程 The new babar sports online mall project quickly builds a tutorial
    码云,git使用 教程-便签
  • 原文地址:https://www.cnblogs.com/expiator/p/9450264.html
Copyright © 2011-2022 走看看