美文网首页
Java 虚拟机 | CAS 比较并交换

Java 虚拟机 | CAS 比较并交换

作者: 彭旭锐 | 来源:发表于2021-01-03 18:37 被阅读0次

点赞关注,不再迷路,你的支持对我意义重大!

🔥 Hi,我是丑丑。本文 「Java 路线」导读 —— 他山之石,可以攻玉 已收录,这里有 Android 进阶成长路线笔记 & 博客,欢迎跟着彭丑丑一起成长。(联系方式在 GitHub)


前言


目录


前置知识

这篇文章的内容会涉及以下前置 / 相关知识,贴心的我都帮你准备好了,请享用~


2. 什么是原子操作?

原子操作(atomic operation)指:不可被分割的一个或一系列操作。在 Java 中,可以使用「锁」和 「自旋 CAS」来实现原子操作。

Editting...


3. CAS 存在的问题

3.1 ABA 问题:无法感知 ABA 的修改过程

在 CAS 操作中,会检查值是否符合预期值,符合则认为没有被修改过。但如果这个值原来是「A」,被修改为「B」,又被改为「A」,CAS 操作时无法感知的。

解决思路是增加时间戳或版本号,例如 JDK 1.5 中就提供了 AtomicMarkableReference(带更新标志位)和 AtomicStampedReference(带版本号),这些类的 CAS 操作除了检查值是否符合预期外,还会检查当前「标志位 / 版本号」是否也符合预期,这样就解决了 ABA 问题。

3.2 开销问题:长时间自旋开销大

在锁资源竞争紧张的情况下,会导致自旋 CAS 会长时间不成功,增大了 CPU 负载。

3.3 只能保证一个变量的原子操作

对一个变量进行 自旋 CAS 操作时,可以保证原子性。但如果对多个变量进行操作时,自旋 CAS 就无法保证原子性。

解决思路是将多个变量合并为一个变量,例如 JDK 1.5 中就提供了 AtomicReference 来保证引用对象之间的原子性。

public static AtomicReference<User> atomicUserRef = new AtomicReference<>();

User user  = new User("peng", 0);
atomicUserRef.set(user)
User newUser  = new User("xurui", 1);
atomicUserRef.compareAndSet(user, newUser);

4. 原子操作类

从 JDK 1.5 开始,Java 提供了一系列原子操作类,具体可以划分为以下四种:

4.1 基本类型

  • AtomicBoolean
  • AtomicInteger
  • AtomicLong

4.2 数组

  • AtomicIntegerArray
  • AtomicLongArray
  • AtomicReferenceArray

4.3 引用

  • AtomicReference
  • AtomicMarkableReference(带更新标志位)
  • AtomicStampedReference(带版本号)

4.4 字段

  • AtomicIntegerFieldUpdater
  • AtomicLongFieldUpdater
  • AtomicReferenceFieldUpdater

5. 总结

  • CAS 实现原子操作存在三大问题,即:「ABA 问题:无法感知 ABA 的修改过程」、「开销问题:长时间自旋开销大」和「只能保证一个变量的原子操作」;
  • 从 JDK 1.5 开始,Java 提供了一系列原子操作类。

创作不易,你的「三连」是丑丑最大的动力,我们下次见!

相关文章

网友评论

      本文标题:Java 虚拟机 | CAS 比较并交换

      本文链接:https://www.haomeiwen.com/subject/yrtuoktx.html