【并发编程】什么是CAS?Java是如何实现CAS操作的?


目录

一.什么是CAS?

二.Java中如何实现CAS操作?


一.什么是CAS?

在Java并发编程中,CAS 代表 "Compare-And-Swap"(交换并比较),这是一种用于实现无锁编程的原子操作。CAS操作通常用于多线程环境中,以确保在没有使用传统锁的情况下,能够安全地更新共享数据。CAS是通过CPU级别的原子指令来实现的,这意味着一个CAS操作就是一个原子操作,该操作一旦开始就不能被打断,必须等待它完成。

CAS操作包含三个用到的值:

  • 内存值(V):这是要更新的变量的当前值。
  • 旧的预期值(A):这是执行CAS操作前,线程预期的内存值。
  • 要更新的新值(B):如果当前值与预期值相匹配,那么将内存值更新为这个新值。
boolean CAS(V, A, B)

这个操作会原子性地检查内存值是否等于旧的预期值(A),如果是,则将内存值更新为新值(B),并返回true表示操作成功。如果内存值不等于预期值,表示在CAS操作执行之前,其他线程已经修改了这个值,那么操作将不会执行更新,而是返回false。

如下图所示ACS操作再修改数据的时候,首先会将原值拿出来保存,计算修改后的值也进行保存,在真正修改之前会先取出现在目标数据的值,并且进行判断俩次取出来的值是否相同,如果相同那么就正常进行修改;如果不相同,那就说明在俩次取值的过程中,目标数据已经被其他线程修改过了,那么就继续重复上述操作,只有在原值和现在的值相同的情况下才进行更新替换。


 

在上述过程中,我们可以看出ASC操作并没有对某个变量进行加锁,它主要是通过不断的判断某个值是否已经被修改来保证数据的一致性的,这也就意味着一直有一个线程来干这件事。

使用CAS的优点包括:

  • 无锁设计:CAS操作允许无锁的线程安全编程,这可以减少线程竞争和锁的开销。
  • 性能:在某些情况下,CAS操作比使用锁具有更高的性能,特别是在高并发环境下。
  • 避免死锁:由于没有使用锁,因此使用CAS可以避免死锁问题。

然而,CAS也有其缺点,比如:

  • ABA问题:由于CAS检查的是值而不是内存地址,如果一个值在被读取和比较期间被修改并又恢复了原值(即发生了ABA情况),CAS操作可能会错误地认为值没有变化。
  • 循环延迟:在高竞争环境下,CAS操作可能会导致线程不断自旋尝试更新值,这可能导致CPU资源的浪费。

二.Java中如何实现CAS操作?

在Java中我们可以通过UnSafe这个类来实现CAS操作,该类位于sun.misc包下。

Unsafe类提供了compareAndSwapObjectcompareAndSwapIntcompareAndSwapLong方法来实现的对Object、int、long类型的 CAS 操作

/**
 * 以原子方式更新字段的值
 * @param o        要操作的对象
 * @param offset   对象字段的内存偏移量
 * @param expected 期望的旧值
 * @param x        要设置的新值
 * @return 如果值被成功更新,则返回 true;否则返回 false
 */ 
public final boolean compareAndSwapObject(Object o, long offset,
                                          Object expected,
                                          Object x) {
    return theInternalUnsafe.compareAndSetReference(o, offset, expected, x);
}

public final boolean compareAndSwapInt(Object o, long offset,
                                       int expected,
                                       int x) {
    return theInternalUnsafe.compareAndSetInt(o, offset, expected, x);
}


public final boolean compareAndSwapLong(Object o, long offset,
                                        long expected,
                                        long x) {
    return theInternalUnsafe.compareAndSetLong(o, offset, expected, x);
}



 本次的分享就到此为止了,希望我的分享能给您带来帮助,创作不易也欢迎大家三连支持,你们的点赞就是博主更新最大的动力!如有不同意见,欢迎评论区积极讨论交流,让我们一起学习进步!有相关问题也可以私信博主,评论区和私信都会认真查看的,我们下次再见

猜你喜欢

转载自blog.csdn.net/m0_69519887/article/details/141065772