zoukankan      html  css  js  c++  java
  • CAS

    本文介绍CAS、通过案例去演示CAS、CAS的应用场景、如何利用CAS进行原子操作、CAS的缺点。

    概述

      CAS是一种思想,使用并发场景,是一种原子性的操作,实现不能被其他线程打断的情况。

      思路:我认为他应该是A,如果是我就修改,如果不是我就放弃他,可以避免多人修改引发的问题。

      具体参数:内存值、预期值、修改值,只有当内存值和预期值相等的时候,才会去修改;利用CPU的指令保证他的原子性。

    代码示例

      两个线程都去修改公共变量,只有一个可以修改成功,示例代码如下所示。

      

    package com.yang.cas;
    
    import javax.management.relation.RoleUnresolved;
    
    /**
     * 模拟CAS操作
     */
    public class SimulatedCASDemo implements Runnable {
        private volatile int value;
    
        public synchronized int compareAndSwap(int expectedValue, int newValue) {
            int oldValue = value;
            if (oldValue == expectedValue) {
                value = newValue;
            }
            return value;
        }
    
        @Override
        public void run() {
            compareAndSwap(0, 1);
        }
    
        /**
         * 两个线程都去修改参数,只有个线程可以修改成功
         * 最终的输出结果为1
         * @param args
         * @throws InterruptedException
         */
        public static void main(String[] args) throws InterruptedException {
            SimulatedCASDemo simulatedCASDemo=new SimulatedCASDemo();
            Thread thread1=new Thread(simulatedCASDemo);
            Thread thread2=new Thread(simulatedCASDemo);
            thread1.start();
            thread2.start();
            thread1.join();
            thread2.join();
            System.out.println(simulatedCASDemo.value);
        }
    }
    

    应用场景

       乐观锁 

      并发容器:concurrentHashMap

      原子类

    原子类如何实现CAS

      原子类AtomicInteger加载unsafe工具,用来直接操作内存数据;用volatile 修饰value字段,保证可见性。

      Unsafe可以拿到内存地址,部分代码如下所示:

      

    static {
            try {
                valueOffset = unsafe.objectFieldOffset
                    (AtomicInteger.class.getDeclaredField("value"));
            } catch (Exception ex) { throw new Error(ex); }
        }
    
        private volatile int value;
    
    
    
    .........................
    public final int getAndAddInt(Object var1, long var2, int var4) { int var5; do { var5 = this.getIntVolatile(var1, var2); } while(!this.compareAndSwapInt(var1, var2, var5, var5 + var4)); return var5; }

     CAS缺点

      1.ABA问题:先修改为A,再修改为B,再修改为A,检查和我的值是否相等,乐观锁可以加个版本号

      2.自旋时间较长

  • 相关阅读:
    ssh 无密码互通
    React之jsx转js
    分布式事务参考
    js跨域解决方案
    idea编译时JDK版本变化
    计数算法
    Rocketmq消息持久化
    rocketmq安装
    nginx高可用配置
    nginx负载均衡设置
  • 原文地址:https://www.cnblogs.com/cnxieyang/p/12761752.html
Copyright © 2011-2022 走看看