共计 1491 个字符,预计需要花费 4 分钟才能阅读完成。
一个小伙伴私信我,他说遇到了一个对于 CAS 机制的问题,他认为面试官问的是 CAS 实现单点登录。
心想,这个问题我熟啊,而后就依照单点登录的思路去答复,后果面试官始终点头。
他来和我说,到了面试完结都没明想白本人答复这么好,怎么就没有当场给我发 offer 呢?
实际上,面试官问的是并发编程中的 CAS 机制。
上面咱们来看看普通人和高手对于 CAS 机制的答复吧
普通人:
CAS,是并发编程中用来实现原子性功能的一种操作,嗯,它相似于一种乐观锁的机制,能够保障并发状况下对共享变量的值的更改的原子性。
嗯,像 AtomicInteger 这个类中,就用到了 CAS 机制。嗯…
高手:
CAS 是 Java 中 Unsafe 类外面的办法,它的全称是 CompareAndSwap,比拟并替换的意思。它的次要性能是可能保障在多线程环境下,对于共享变量的批改的原子性。
我来举个例子,比如说有这样一个场景,有一个成员变量 state,默认值是 0,
定义了一个办法doSomething()
,这个办法的逻辑是,判断 state 是否为 0,如果为 0,就批改成 1。
这个逻辑看起来没有任何问题,然而在多线程环境下,会存在原子性的问题,因为这里是一个典型的,Read – Write 的操作。
个别状况下,咱们会在 doSomething()这个办法上加同步锁来解决原子性问题。
然而,加同步锁,会带来性能上的损耗,所以,对于这类场景,咱们就能够应用 CAS 机制来进行优化
这个是优化之后的代码
在 doSomething()办法中,咱们调用了 unsafe 类中的 compareAndSwapInt()办法来达到同样的目标,这个办法有四个参数,
别离是:以后对象实例、成员变量 state 在内存地址中的偏移量、预期值 0、冀望更改之后的值 1。
CAS 机制会比拟 state 内存地址偏移量对应的值和传入的预期值 0 是否相等,如果相等,就间接批改内存地址中 state 的值为 1.
否则,返回 false,示意批改失败,而这个过程是原子的,不会存在线程平安问题。
CompareAndSwap 是一个 native 办法,实际上它最终还是会面临同样的问题,就是先从内存地址中读取 state 的值,而后去比拟,最初再批改。
这个过程不论是在什么层面上实现,都会存在原子性问题。
所以呢,CompareAndSwap 的底层实现中,在多核 CPU 环境下,会减少一个 Lock 指令对缓存或者总线加锁,从而保障比拟并替换这两个指令的原子性。
CAS 次要用在并发场景中,比拟典型的应用场景有两个。
- 第一个是 J.U.C 外面 Atomic 的原子实现,比方 AtomicInteger,AtomicLong。
- 第二个是实现多线程对共享资源竞争的互斥性质,比方在 AQS、ConcurrentHashMap、ConcurrentLinkedQueue 等都有用到。
以上就是我对这个问题的了解。
总结
最近大家也发现了我的文章内容在高手答复局部的变动。
有些小伙伴说,你面试怎么还能带图来,显著舞弊啊。
其实次要是最近很多的面试题都偏底层,而底层的内容涵盖的知识面比拟广,大家平时简直没有接触过。
所以,如果我想要去把这些常识传递给大家,就得做很多的图形和内容构造的设计,否则大家看完之后还是一脸懵逼。
好的,本期的普通人 VS 高手面试系列就到这里完结了,喜爱的敌人记得点赞珍藏。
我是 Mic,一个工作了 14 年的 Java 程序员,咱们下期再见。
版权申明:本博客所有文章除特地申明外,均采纳 CC BY-NC-SA 4.0 许可协定。转载请注明来自
Mic 带你学架构
!
如果本篇文章对您有帮忙,还请帮忙点个关注和赞,您的保持是我一直创作的能源。欢送关注同名微信公众号获取更多技术干货!