• 原子变量与CAS算法小结


    CAS算法

    • CAS(compare-and-swap)是一种硬件对并发的支持,针对多处理器操作而设计的处理器中的一种特殊指令,用于管理对共享数据的并发访问。

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

    • CAS 包含了 3 个操作数:
      需要读写的内存值V
      进行比较的值A
      拟写入的新值B

    • 当且仅当V的值等于A时,CAS通过原子方式用新值更新V的值,否则不会执行任何操作。

    CAS操作过程如下所示

    CAS操作过程

    CAS算法模拟

    /**
     * 模拟CAS算法
     *
     * Created by 吴海飞 on 2017-1-22.
     */
    public class TestCompareAndSwap {
        public static void main(String[] args){
            final CompareAndSwap cas = new CompareAndSwap();
    
            for (int i = 0; i < 10; i++ ){
                new Thread(new Runnable() {
                            @Override
                            public void run() {
                                int expectValue = cas.getValue();
                                boolean b = cas.compareAndSet(expectValue, (int)(Math.random() * 101));
                                System.out.println(b);
                            }
                        }
                ).start();
            }
    
        }
    }
    
    class CompareAndSwap{
        private int value;
    
        //获取内存值
        public synchronized int getValue(){
            return this.value;
        }
        //比较
        public synchronized int compareAndSwap(int expectValue,int newValue){
            int oldValue = this.value;
            if(oldValue == expectValue){//如果期望值等于旧值
                this.value = newValue;
            }
            return oldValue;
        }
    
        public synchronized boolean compareAndSet(int expectValue,int newValue){
            return expectValue == compareAndSwap(expectValue, newValue);
        }
    
    }
    

    原子变量

    • 类的小工具包,支持在单个变量上解除锁的线程安全编程。事实上,此包中的类可将 volatile 值、字段和数组元素的概念扩展到那些也提供原子条件更新操作的类。

    • 类 AtomicBoolean、 AtomicInteger、 AtomicLong 和 AtomicReference 的实例各自提供对相应类型单个变量的访问和更新。每个类也为该类型提供适当的实用工具方法。

    • AtomicIntegerArray、 AtomicLongArray 和 AtomicReferenceArray 类进一步扩展了原子操作,对这些类型的数组提供了支持。这些类在为其数组元素提供 volatile 访问语义方面也引人注目,这对于普通数组来说是不受支持的。

    • 核心方法: boolean compareAndSet(expectedValue, updateValue)

      • java.util.concurrent.atomic 包下提供了一些原子操作的常用类:

        1. AtomicBoolean 、 AtomicInteger 、 AtomicLong 、AtomicReference
        2. AtomicIntegerArray 、 AtomicLongArray
        3. AtomicMarkableReference
        4. AtomicReferenceArray
        5. AtomicStampedReference

      原子变量使用Demo

    import java.util.concurrent.atomic.AtomicInteger;
    
    /**
     *一、i++ 的原子性问题:i++ 的操作实际上分为三个步骤“读-改-写”
     *        int i = 10;
     *        i = i++; //10
     *
     *        int temp = i;
     *        i = i + 1;
     *        i = temp;
     * 二、原子变量:在 java.util.concurrent.atomic 包下提供了一些原子变量。
     *      1. volatile 保证内存可见性
     *      2. CAS(Compare-And-Swap) 算法保证数据变量的原子性
     *          CAS 算法是硬件对于并发操作的支持
     *          CAS 包含了三个操作数:
     *          ①内存值  V
     *          ②预估值  A
     *          ③更新值  B
     *          当且仅当 V == A 时, V = B; 否则,不会执行任何操作。
     */
    
    public class AtomicDemo {
        public static void main(String[] args) {
            AtomicData ad = new AtomicData();
            for (int i = 0; i < 10; i++) {
                new Thread(ad).start();
            }
        }
    }
    
    class AtomicData implements Runnable{
        //初始化原子变量
        private AtomicInteger atomicData = new AtomicInteger(0);
    
        @Override
        public void run() {
            try {
                Thread.sleep(200);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
    
            System.out.println(getAtomicData());
        }
    
        public int getAtomicData(){
            return atomicData.getAndIncrement();//相当于atomicData++
        }
    
    }
    
  • 相关阅读:
    windows C++ 网络编程
    typedef void (*Fun) (void) 的理解——函数指针——typedef函数指针
    获取屏幕分辨率(C/C++)
    随手记
    【SQLite】可视化工具SQLite studio
    C++宽窄字符串转换
    并发编程1——一个简单的多线程程序
    css中:after和:before的作用及使用方法
    uniapp—App—自定义导航栏
    vue—封装无数据时默认展示组件
  • 原文地址:https://www.cnblogs.com/haifeiWu/p/9079588.html
Copyright © 2020-2023  润新知