Java比较和交换示例– CAS算法
1. 乐观锁与悲观锁 (Optimistic and Pessimistic Locking)
传统的锁定机制(例如 Java 中的 synchronized 关键字)被称为悲观锁(Pessimistic Locking)技术。它要求线程在访问共享资源前必须先获得锁,确保没有其他线程会干扰操作(即锁定对象),然后才允许访问实例或方法。
这就好比说:“请先关上门,否则其他干扰者会进来重新整理您的东西。”
尽管上述方法是安全的且确实有效,但它会给应用程序的性能带来显著损失。原因很简单:等待锁的线程无法执行任何操作,直到它们有机会获取锁并执行受保护的操作为止。
存在一种在性能上更有效且本质上是乐观的方法。使用这种方法,线程可以直接进行更新,假设在操作期间不会发生干扰。此方法依靠冲突检测来确定更新期间是否存在来自其他线程的干扰;在这种情况下,操作将失败,线程可以选择重试(或不重试)。
乐观锁的方法就像那句老话所说:“请求原谅比获得许可更容易(Easier to ask forgiveness than permission)”,这里的“容易”意味着“更高效”。
比较并交换(Compare-And-Swap, CAS) 就是这种乐观方法的一个典型例子,我们将在下面详细讨论。
2. 比较并交换算法 (Compare and Swap Algorithm)
CAS 算法将存储位置的内容与给定值进行比较,并且只有当它们相同时,才将该存储位置的内容修改为给定的新值。这是作为单个原子操作(Atomic Operation)完成的。原子性保证了新值是根据最新信息计算的;如果与此同时值已被另一个线程更新,则写入将失败。操作结果必须表明是否执行了替换;这可以通过简单的布尔响应(此变量通常称为“比较设置”)来完成,也可以通过返回从内存位置读取的值(而不是写入该值)来完成。
CAS 操作包含三个操作数:
- 内存位置 V:必须替换值的存储位置。
- 预期原值 A:线程上次读取的旧值。
- 新值 B:应该写在 V 上的新值。
CAS 的逻辑可以表述为:“我认为 V 应该具有值 A;如果可以,则将 B 放在此处;否则不要更改它,但要告诉我操作失败了。”CAS 是一种乐观技术,它希望成功进行更新,并且如果自从上次检查变量以来另一个线程更新了该变量,它可以检测到失败。
3. Java CAS 示例 (Java Compare and Swap Example)
让我们通过一个例子来了解整个过程。假设 V 是存储值 10 的内存位置。有多个线程想要递增此值并将递增后的值用于其他操作,这是一种非常实际的场景。让我们分步分解整个 CAS 操作:
1) 线程准备阶段
线程 1 和线程 2 都想递增该值。它们都读取了当前值 10,并计算出目标值为 11。
- 当前内存值:
V = 10 - 线程预期值:
A = 10 - 线程新值:
B = 11
2) 线程 1 执行 CAS
线程 1 首先发起请求,将 V 与它的预期值 A 进行比较:
- 状态:
V = 10,A = 10,B = 11
if (A == V) {
V = B; // 更新成功
} else {
// 操作失败
return V; // 返回当前值
}显然,V 的值等于 A,因此 V 将被覆盖为 11,操作成功。
3) 线程 2 执行 CAS
线程 2 随后到来,尝试执行与线程 1 相同的操作:
- 状态:
V = 11(已被线程 1 修改),A = 10(线程 2 旧的预期值),B = 11
if (A == V) {
V = B;
} else {
// 操作失败
return V;
}4) 线程 2 重试
在这种情况下,V (11) 不等于 A (10),因此不替换值,操作失败。线程 2 获取到当前最新值 11,再次使用新值重试此操作:
- 新状态:
V = 11,A = 11,B = 12
这一次,条件得到满足,增量值 12 被成功写入,操作返回成功。
总结
总而言之,当多个线程尝试使用 CAS 同时更新同一变量时,只有一个线程会获胜并更新该变量的值,其余线程会发现操作失败。但是,失败者并不会因为线程阻塞而受到惩罚。它们可以自由地重试该操作(自旋),或者根据业务逻辑放弃操作。
这就是 Java 中原子操作支持背后的简单但重要的概念。
说明:本文基于 Java 5 引入的 java.util.concurrent.atomic 包机制编写。CAS 算法是现代 Java 并发编程(如 AtomicInteger、AtomicLong 等类)的底层基础,适用于高并发场景下的无锁编程。
版权声明:本文为原创文章,版权归 戴老师的博客 所有,转载请联系博主获得授权。
本文地址:https://1diff.fun/archives/java-bi-jiao-he-jiao-huan-shi-li--cas-suan-fa.html
如果对本文有什么问题或疑问都可以在评论区留言,我看到后会尽量解答。