• 原子操作CAS


    一、什么是原子操作

    不可被中断的一个或者一系列操作、

    CAS是Compare And Set的缩写,是以一种无锁的方式实现并发控制。在实际情况下,同时操作同一个对象的概率非常小,所以多数加锁操作做的是无用功,CAS以一种乐观锁的方式实现并发控制

    二、实现原子操作的方式

    Java可以通过锁和循环CAS的方式实现原子操作。

    三、CAS( Compare And Swap )  为什么要有CAS?

    Compare And Swap就是比较并且交换的一个原子操作,由Cpu在指令级别上进行保证。

    为什么要有CAS:因为通过锁实现原子操作时,其他线程必须等待已经获得锁的线程运行完以后才能获得资源,这样就会占用系统的大量资源

    四、CAS包含哪些参数?

    CAS包含三个参数:1、变量所在内存地址V;2、变量对应的值A;3、我们将要修改的值B。如果说V上的变量的值是A的话,就用B重新赋值,如果不是A,那就什么事也不做,操作的返回结果原值是多少。

    循环CAS:在一个(死)循环【for(;;)】里不断进行CAS操作,直到成功为止(自旋操作即死循环)。

    五、CAS的原理

    利用了现代处理器都支持的CAS的指令,循环这个指令,直到成功为止

    六、CAS实现原子操作的三大问题

    1、 ABA问题:其他的线程把值改成了B,很快改成了A,原子操作的线程发现值是A就修改,这样会有问题。解决ABA,引入版本号:1A-》2C-》3A

    2、 循环时间很长的话,cpu的负荷比较大

    3、 对一个变量进行操作可以,同时操作多个共享变量有点麻烦

    七、CAS线程安全面试点

    通过硬件层面的阻塞实现原子操作的安全

     八、原子操作类

    jdk提供了许多根据CAS思路产生的原子操作类;总结下来可以分成以下几类:

    更新基本类型类:AtomicBoolean,AtomicInteger,AtomicLong,AtomicReference
    更新数组类:AtomicIntegerArray,AtomicLongArray,AtomicReferenceArray
    更新引用类型:AtomicReference,AtomicMarkableReference,AtomicStampedReference
    原子更新字段类: AtomicReferenceFieldUpdater,AtomicIntegerFieldUpdater,AtomicLongFieldUpdater

    例子:我们只是看其中的及格就行了

    AtomicInteger (这里我们要注意incrementandget()和getAndincrement())
    package pers.cc.cas;
    
    import java.util.concurrent.atomic.AtomicInteger;
    
    public class AtomicIntegerTest {
        /**
         * 定义一个线程安全的Integer并设定初始值为0
         */
        static AtomicInteger atomicInteger = new AtomicInteger(0);
    
        static int i = 0;
    
        public static void main(String[] args) throws InterruptedException {
            for (int j = 0; j < 100000; j++) {
                Thread addThread = new Thread(new Runnable() {
                    @Override
                    public void run() {
                        // 原子的增加1
                        atomicInteger.incrementAndGet();
                        i++;
                    }
                });
                addThread.start();
            }
            Thread.sleep(2000);
            System.out.println(atomicInteger.get());
            System.out.println(i);
        }
    }

    运行结果:

    100000
    99998

    AtomicMarkableReference() 和 AtomicStampedReference()--区别?

    --一个是通过版本号,一个是通过boolean值

    参考文章:

    https://blog.csdn.net/u010904188/article/details/87712060

    https://blog.csdn.net/u010963948/article/details/79052213

  • 相关阅读:
    webservice未能加载文件或程序集“**.DLL”或它的某一个依赖项。
    四方在线打印控件使用(简介)
    C#图片处理高级应用(裁剪,缩放,清晰度,水印)
    基于Socket实现TCP/IP通讯
    委托
    FTP主配置文件详解
    关于解决RedHat6.0以上版本:Loaded plugins: product-id, refresh-packagekit, security, subscription-manager
    Markdown学习
    网页HTML1,第一天学习。
    实现公众号留言的微信小程序--欢迎大家多多交流
  • 原文地址:https://www.cnblogs.com/lys-lyy/p/11037985.html
Copyright © 2020-2023  润新知