一位小伙伴给我发了私信。他说他遇到了一个关于CAS机制的问题。他以为面试官问的是CAS,实现单点登录。我心想,这道题我很熟,然后就按照单点登录的思路回答了,面试官却一直摇头。他来跟我说,面试结束的时候,他不明白为什么他回答这么好,那他为什么不当场给我发offer呢?其实面试官问的是并发编程中的CAS机制。让我们来看看普通人和专家对CAS机制的回答。普通人:CAS是并发编程中用来实现原子功能的操作。嗯,类似于可以保证并发的乐观锁机制。共享变量值更改的原子性。嗯,CAS机制被用在像AtomicInteger这样的类中。嗯...师父:CAS是Java中Unsafe类中的一个方法。它的全称是CompareAndSwap,意思是比较和交换。它的主要作用是保证在多线程环境下修改共享变量的原子性。让我举一个例子。例如,有这样一个场景。有一个成员变量state,默认值为0,定义了一个方法doSomething()。该方法的逻辑是判断state是否为0,如果为0则修改。into1.这个逻辑看似没有什么问题,但是在多线程环境下,就会出现原子性问题,因为这是一个典型的Read-Write操作。一般情况下,我们都会在doSomething()方法中加一个同步锁来解决原子性问题。但是加同步锁会带来性能的损失,所以对于这种场景,我们可以使用CAS机制来优化,这就是优化后的代码。在doSomething()方法中,我们调用不安全类的compareAndSwapInt()方法来达到同样的目的。该方法有四个参数,分别是:当前对象实例、成员变量state在内存地址中的偏移量、期望值0、期望变化后的值1。CAS机制会比较state内存地址偏移量对应的值是否等于传入的期望值0,如果相等,直接修改内存地址中state的值为1,否则返回false,说明修改失败,而且这个过程是原子的,不会有线程安全问题。CompareAndSwap是一种本机方法。其实最后还是会面临同样的问题,就是先从内存地址读取state的值,然后比较,最后修改。不管这个过程在哪个层级实现,都会存在原子性问题。因此,在CompareAndSwap的底层实现中,在多核CPU环境下,会增加一条Lock指令来锁定缓存或总线,以保证这两条指令比较替换的原子性。CAS主要用于并发场景,典型的使用场景有两种。第一个是J.U.C中Atomic的原子实现,比如AtomicInteger和AtomicLong。二是实现多线程竞争共享资源的互斥性,比如AQS、ConcurrentHashMap、ConcurrentLinkedQueue等都有用。以上是我对这个问题的理解。总结最近大家也发现了我在专家解答区文章内容的变化。有朋友说,怎么还带着照片去面试,明显是作弊。其实主要是最近的面试题很多都是low-level的,而且low-level的内容涵盖的知识面很广,大家很少接触到。所以,如果我想把这些知识传授给大家,就得做大量的图文和内容结构设计,不然大家看了还是一头雾水。好了,本期普通人VS专家访谈系列到此结束,喜欢的朋友记得点赞收藏。我是Mic,一名工作了14年的Java程序员。下次见。版权声明:除特别声明外,本博客所有文章均采用CCBY-NC-SA4.0许可协议。转载请注明来自Mic带你学建筑!如果本文对您有帮助,请给个关注和点赞。您的坚持是我不断创作的动力。欢迎关注同名微信公众号获取更多技术干货!
