面试官超级喜欢问的CAS问题
前言
自学了一年JAVA阿巴阿巴终于约到了面试,这次面试官让她谈谈对CAS的理解。
回去等通知
如果对CAS完全不了解的同学建议先去看看相关的博客了解了基本的原理,再来看面试的时候如何解答
面试官: 对CAS有了解吗?可以讲讲吗?
阿巴阿巴: 了解一些,CAS全称Compare And Swap,也就是比较和交换。
阿巴阿巴: CAS的思想比较简单,主要涉及到三个值:当前内存值V、预期值(旧的内存值)O、即将更新的内存值U,当且仅当预期值O与当前内存值V相等时,将内存值V修改为更新值U,并返回true,否则返回false。
面试官: 还有嘛?CAS的使用场景知道吗?
阿巴阿巴: 额...应该差不多了,CAS好像在并发包里使用到了
面试官: 好,CAS有啥缺点吗?
阿巴阿巴: 额....好..好像有个ABA的问题,好像是用AtomicStampedReference解决
面试官: 还有其他缺点吗?
阿巴阿巴: 额...记不太清了....
面试官: 行,那你这边先回去等通知哈😈
阿巴阿巴: 好的~
当场发offer
面试官: CAS了解吗?讲讲
阿巴阿巴: CAS全称Compare and Swap,也就是比较和交换。
阿巴阿巴: CAS的思想比较简单,主要涉及到三个值:当前内存值V、预期值(旧的内存值)O、即将更新的内存值U,当且仅当预期值O与当前内存值V相等时,将内存值V修改为更新值U,返回true,否则返回false。
阿巴阿巴: CAS主要使用在一些需要上锁的场景充当乐观锁解决方案,一般在一些简单且要上锁的操作但又不想引入锁场景,这时候来使用CAS代替锁。
阿巴阿巴: CAS主要涉及到三个问题:ABA问题、自旋带来的消耗、CAS只能单变量
面试官: 可以详细讲一下这三个问题吗?
阿巴阿巴: ABA问题是指有一个线程t1在进行CAS操作时,其他线程t2将变量A改成了B,然后又将其改成A,这时候t1发现A并没有改变,因此进行了交换操作,由于在交换操作进行前变量A其实是有变化的,只不过最终又修改回A了,此A非彼A,这时候进行交换操作在一些业务场景下很可能要出问题,要解决ABA问题有2种方案。
阿巴阿巴: 方案一:在对变量进行操作的时候给变量加一个版本号,每次对变量操作都将版本号加1,常见在数据库的乐观锁中可见。
阿巴阿巴: 方案二:Java提供了相应的原子引用类AtomicStampedReference,它通过包装[E,Integer]的元组来对对象标记版本戳stamp,从而避免ABA问题。
阿巴阿巴: 自旋带来的消耗CAS自旋如果很长时间都不成功,这会给CPU带来很大的开销
阿巴阿巴: 解决方案:1、代码层面破坏掉for循坏,设置合适的循环次数。2、使用JVM能支持处理器提供的pause指令来提升效率,它可以延迟流水线执行指令,避免消耗过多CPU资源。
阿巴阿巴: CAS只能单变量对于一个共享变量,可以使用CAS方式来保证原子操作,但是当多个共享变量时,那就无法使用CAS来保证原子性。JDK1.5开始,提供了AtomicReference类来保证引用对象之前的原子性,就可以把多个变量放在一个对象里来进行CAS操作。
阿巴阿巴: 在JDK1.5中新增的java.util.concurrent(JUC),就是建立在CAS之上的,一般来说CAS这种乐观锁适合读多写少的场景。
面试官: 不错,明天可以来上班了。
阿巴阿巴: 好的~
#Java开发##阿里巴巴##面经#