当前位置:首页 > 数码 > CAS-深入理解-机制-一个保证原子操作的技术-and-Swap-Compare

CAS-深入理解-机制-一个保证原子操作的技术-and-Swap-Compare

admin8个月前 (04-18)数码38

概述

CAS(Compare and Swap)是一种乐观锁机制,它基于硬件指令实现原子操作,可以保证多线程对共享变量的安全访问,而不需要使用传统的互斥锁。

CAS机制的原理是比较内存中的值和预期值,如果相等则进行更新操作,否则不进行任何操作。这种方式避免了传统锁机制中的线程阻塞和唤醒操作,从而提高了并发性能。

Java 中的 CAS 实现

在 Java 中,Atomic 类和 AtomicReference 类提供了 CAS 操作。Atomic 类用于基本数据类型(如 int、long、boolean 等)的原子操作,而 AtomicReference 类用于引用类型的原子操作。

这些类提供了以下原子更新方法:

  • compareAndSet(expectedValue, newValue):如果当前值等于 expectedValue,则更新为 newValue
  • getAndSet(newValue):获取当前值并更新为 newValue
  • incrementAndGet():将当前值加一并返回

CAS 的优点

  • 提高并发性能:避免了线程阻塞和唤醒操作,提高了吞吐量。
  • 简化代码:与传统的锁机制相比,CAS 操作更加简洁和易于使用。
  • 支持非阻塞算法:可以使用 CAS 实现非阻塞算法和数据结构,如并发队列和自旋锁。

CAS 的限制

    and
  • 硬件依赖性:CAS 机制需要硬件支持,并非所有平台和处理器都支持 CAS 指令。
  • ABA 问题:在高并发情况下,可能出现 ABA 问题,即共享变量的值在 CAS 操作之前和之后都相同,但中间被其他线程修改过,导致 CAS 操作成功但并无预期效果。

ABA 问题的解决方法

可以使用版本号或标记位来解决 ABA 问题。版本号或标记位会随着共享变量的值的变化而变化,这样就可以在 CAS 操作时检查版本号或标记位是否一致,以保证操作的正确性。

使用场景

CAS 机制适用于以下场景:

  • 高并发场景:需要保证并发访问共享变量的安全性和效率。
  • 非阻塞算法:实现非阻塞队列、并发计数器、自旋锁等。
  • 乐观锁:实现数据库中的乐观锁操作和分布式锁的管理。

总结

CAS(比较并交换)机制是一种乐观锁机制,可以有效地保证多线程对共享变量的安全访问,提高并发性能。在 Java 中,可以使用 Atomic 类和 AtomicReference 类来实现 CAS 操作。虽然 CAS 机制存在一些限制,但它在合适的场景下可以显著提高系统的并发性能和吞吐量。


CAS原理以及CAS带来的三大问题

参考:

CAS :Compare and Swap,即比较再交换。

CAS算法理解 :CAS是一种无锁算法,CAS有3个操作数,内存值E,旧的预期值V,要修改的新值N。当且仅当预期值V和内存值E相同时,将内存值E修改为N,否则什么都不做。

CAS算法图解 :

上图描述了CAS的原理,以及带来的三大问题以及问题出现的位置。

问题 因为CAS需要在操作值的时候,检查值有没有发生变化,如果没有发生变化则更新,但是如果一个值原来是A,变成了B,又变成了A,那么CAS进行检查的时候发现它的值没有发生变化,但是实际上却变化了。ABA问题的解决思路就是使用版本号。在变量前面加上版本号,每次变量更新的时候把版本号加1,那么A->B->A就会变成1A->2B->3A。从Java 1.5开始,JDK的Atomic包里提供了一个类AtomicStampedReference来解决ABA问题。这个类的compareAndSet方法的作用是首先检查当前引用是否等于预期引用,并且检查当前的标志是否等于预期标志,如果全部相等,则以原子方式将该应用和该标志的值设置为给定的更新值。

2.循环时间长开销大 自旋CAS如果长时间不成功,会给CPU带来非常大的执行开销,如果JVM能支持处理器提供的pause指令,那么效率会有一定的提升。pause指令有两个作用:第一,它可以延迟流水线执行指令(de-pipeline),使CPU不会消耗过多的执行资源,延迟的时间取决于具体实现的版本,在一些处理器上延迟时间是零;第二,它可以避免在循环的时候因内存顺序冲突(Memory Order Violation)而引起CPU流水线被清空,从而提高CPU的实行效率。

3.只能保证一个共享变量的原子操作 当对一个共享变量执行操作时,我们可以使用循环CAS的方式来保证原子操作,但是对多个共享变量操作时,循环CAS就无法保证操作的原子性,这个时候可以用锁。还有一个取巧的办法,就是把多个共享变量合并成一个共享变量来操作。比如,有两个共享变量i=2,j=a,合并一下ji=2a,然后用CAS来操作ij。从Java 1.5开始,JDK提供了AtomicReference类来保证引用对象之前的原子性,就可以把多个变量放在一个对象里来进行CAS操作。

CAS是什么意思?该如何完成?

CAS是CompareAndSwap的缩写,是一种无锁原子算法,映射到操作系统就是一条CPU的原子指令,其作用是让CPU先进行比较两个值是否相等,然后原子地更新某个位置的值。

如果您是在问如何完成CAS任务,那么我需要更多的信息才能回答您的问题。CAS任务是什么?是由谁分配的?有哪些要求和限制?等等。

免责声明:本文转载或采集自网络,版权归原作者所有。本网站刊发此文旨在传递更多信息,并不代表本网赞同其观点和对其真实性负责。如涉及版权、内容等问题,请联系本网,我们将在第一时间删除。同时,本网站不对所刊发内容的准确性、真实性、完整性、及时性、原创性等进行保证,请读者仅作参考,并请自行核实相关内容。对于因使用或依赖本文内容所产生的任何直接或间接损失,本网站不承担任何责任。

标签: CAS