关于java:面试普通人VS高手系列能谈一下CAS机制吗

5次阅读

共计 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 次要用在并发场景中,比拟典型的应用场景有两个。

  1. 第一个是 J.U.C 外面 Atomic 的原子实现,比方 AtomicInteger,AtomicLong。
  2. 第二个是实现多线程对共享资源竞争的互斥性质,比方在 AQS、ConcurrentHashMap、ConcurrentLinkedQueue 等都有用到。

以上就是我对这个问题的了解。

总结

最近大家也发现了我的文章内容在高手答复局部的变动。

有些小伙伴说,你面试怎么还能带图来,显著舞弊啊。

其实次要是最近很多的面试题都偏底层,而底层的内容涵盖的知识面比拟广,大家平时简直没有接触过。

所以,如果我想要去把这些常识传递给大家,就得做很多的图形和内容构造的设计,否则大家看完之后还是一脸懵逼。

好的,本期的普通人 VS 高手面试系列就到这里完结了,喜爱的敌人记得点赞珍藏。

我是 Mic,一个工作了 14 年的 Java 程序员,咱们下期再见。

版权申明:本博客所有文章除特地申明外,均采纳 CC BY-NC-SA 4.0 许可协定。转载请注明来自 Mic 带你学架构
如果本篇文章对您有帮忙,还请帮忙点个关注和赞,您的保持是我一直创作的能源。欢送关注同名微信公众号获取更多技术干货!

正文完
 0