网站开发年薪,wordpress 第三方应用,三木做网站,wordpress 怎么切换主题目录
一、自旋
二、CAS
三、什么是 ABA 问题 大家好#xff0c;我是月夜枫#xff0c;通常在面试的时候#xff0c;或者在学习的时候#xff0c;经常性的会遇到一些关于锁的问题#xff0c;尤其是面试官会提出提问#xff0c;你对锁了解的多么#xff1f;你知道锁的原… 目录
一、自旋
二、CAS
三、什么是 ABA 问题 大家好我是月夜枫通常在面试的时候或者在学习的时候经常性的会遇到一些关于锁的问题尤其是面试官会提出提问你对锁了解的多么你知道锁的原理么等等问题于是也就会有后续延伸出来的你知道 CAS 么你知道什么是自旋么今天就分析其中的CAS和自旋的区别。 一、自旋
顾名思义自旋可以理解为“自我旋转”放到程序中就是自我循环比如while循环或者for循环。结合着锁来理解的话就是先获取一次锁如果获取不到锁会不停的循环获取直到获取到。不像普通的锁那样如果获取不到锁就进入阻塞状态。
二、CAS
CAS 是什么它的英文全称是 Compare-And-Swap中文叫做“比较并交换”它是一种思想、一种算法。
CAS算法有3个基本操作数 内存地址V 旧的预期值A 要修改的新值B 在并发场景下各个代码的执行顺序不能确定为了保证并发安全我们可以使用普通的互斥锁比如Java的 synchronized, ReentrantLock等。而CAS的特点是避免使用互斥锁当多个线程并发使用CAS更新同一个变量时只有一个可以操作成功其他都会失败。而且用CAS更新失败的线程并不会阻塞会快速失败并返回一个失败的状态允许你再次尝试。
而Compare-And-SwapCAS是一种原子操作用于实现多线程环境下的同步和并发控制。其基本原理如下 读取内存值首先CAS会读取内存中的一个变量的当前值。 比较内存值和预期值接下来CAS会将读取的值与预期值进行比较。如果两者相等则说明内存中的值没有被其他线程修改。 如果相等则将新值写入内存在比较阶段如果发现内存值与预期值相等CAS会尝试将新值写入内存中。这个写入操作是原子的即在这个过程中不会被其他线程中断。 如果写入成功则操作完成否则重复上述步骤如果写入操作成功CAS完成。如果写入操作失败说明在比较和写入的过程中内存值已经被其他线程修改此时需要重新执行整个CAS操作。
CAS的基本原理就是利用比较和写入的原子性操作来实现对共享变量的原子操作从而避免了传统锁机制中的死锁和线程阻塞问题。
自旋锁和CAS的关系是什么呢
其实他们是两个不同的概念 自旋是一种锁优化的机制在锁优化中『自旋锁』指线程空转重试获取锁避免线程上下文切换带来的开销。
CAS是一种乐观锁机制cas是通过比较并交换失败的时候可以直接返回false不用自旋的获取。只是一般应用场景下cas都会带有重试机制(while或者for实现空转不断尝试获取)。
如果硬有关系那么可以这样理解
自旋锁 循环CAS
我们都知道了这个自旋锁和 CAS 的关系了那么CAS 都有哪些缺点呢
Compare-And-Swap (CAS) 的缺点包括 自旋等待CAS 在执行时会进行自旋等待如果失败则需要重试这会消耗处理器资源。 ABA 问题CAS 只能检测到共享变量的值是否发生了变化但无法检测到变量的值是否经历了类似 A-B-A 的变化这可能导致一些意外的问题。 无法保证公平性CAS 操作是非阻塞的因此无法保证等待线程的公平性可能导致某些线程长时间无法获得执行机会。 无法解决死锁CAS 无法解决死锁问题如果多个线程同时执行 CAS 操作可能导致死锁的发生。 限制性CAS 操作通常只能应用于单个变量对于复杂的数据结构需要额外的处理来实现原子操作。
总的来说CAS 虽然具有高效的特点但也存在着一些局限性和缺点。
既然我们说了这个 CAS 那么面试官不可避免的就会问到既然你了解了 CAS 那么你是不是也对 ABA 问题有了解呢
三、什么是 ABA 问题
我们先来看什么是 ABA 的问题。
ABA问题是在分布式系统中常见的一种数据一致性问题。它的名称来源于三个操作A原始值、B第一个读取、A第二个读取。ABA问题发生在一个线程T1读取了一个共享变量的值A然后另一个线程T2修改了这个共享变量的值为B然后又改回A最后线程T1再次读取这个共享变量的值发现仍然是A。在这种情况下线程T1可能会错误地认为共享变量的值没有改变从而导致数据不一致。
解决ABA问题的常见方案是使用版本号或者标记来跟踪数据的变化。通过在每次数据变化时增加版本号或者标记可以避免ABA问题的发生。另外使用CASCompare and Swap操作也可以解决ABA问题CAS操作会在更新变量时检查变量的值是否仍然是预期值从而避免了ABA问题的发生。
简单的说就是
比如线程1从内存位置V中取出A此时线程2也取出A。且线程2做了一次cas将值改为了B然后又做了一次cas将值改回了A。此时线程1做cas发现内存中还是A则线程1操作成功。这个时候实际上A值已经被其他线程改变过这与设计思想是不符合的。
那么这个问题出现在哪里呢 如果只在乎结果ABA不介意B的存在 没什么问题 如果B的存在会造成影响需要通过 AtomicStampReference加时间戳解 决。
那关于自旋和 CAS 你了解了么