Java并发编程(16)—— 乐观锁、悲观锁和CAS算法实现

如果将悲观锁(Pessimistic Lock)和乐观锁(PessimisticLock 或 OptimisticLock)对应到现实生活中来。悲观锁有点像是一位比较悲观(也可以说是未雨绸缪)的人,总是会假设最坏的情况,避免出现问题。乐观锁有点像是一位比较乐观的人,总是会假设最好的情况,在要出现问题之前快速解决问题。

1.什么是悲观锁?

悲观锁总是假设最坏的情况,认为共享资源每次被访问的时候就会出现问题(比如共享数据被修改),所以每次在获取资源操作的时候都会上锁,这样其他线程想拿到这个资源就会阻塞直到锁被上一个持有者释放。也就是说,共享资源每次只给一个线程使用,其它线程阻塞,用完后再把资源转让给其它线程。

### Java乐观锁悲观锁实现机制 #### 悲观锁实现机制 悲观锁假设最坏的情况,在整个数据处理过程中锁定资源,防止其他线程修改同一份数据。这种方式适用于高并发且写操作频繁的场景[^2]。 在Java中,可以通过`synchronized`关键字或显式的锁(如ReentrantLock)来实现悲观锁: ```java public class PessimisticLockExample { private final Object lock = new Object(); public void writeData() { synchronized (lock) { // 执行写入逻辑 } } public void readData() { synchronized (lock) { // 执行读取逻辑 } } } ``` 上述代码展示了如何利用内置同步机制保护共享资源访问。当一个线程进入临界区时,它会阻止任何其他尝试获取相同监视器对象的线程直到当前线程退出该区域为止。 #### 乐观锁实现机制 与悲观锁不同的是,乐观锁认为大多数情况下不会发生冲突,因此不需要在整个事务期间保持锁定状态;只有在提交更新前才会检查是否有其他更改发生过。如果检测到变化,则回滚并重试交易过程[^3]。 一种常见的乐观锁实现方法是使用版本号控制——每当记录被修改时增加其版本计数,并在每次更新之前验证这个值是否未改变。另一种更高效的方式是在硬件层面支持原子指令集的基础上构建高级抽象APIs, 如 `java.util.concurrent.atomic` 包下的类所提供的功能[^1]。 下面是一个简单的例子展示如何运用`AtomicInteger` 类来进行无锁编程: ```java import java.util.concurrent.atomic.AtomicInteger; public class OptimisticLockExample { private AtomicInteger value = new AtomicInteger(); public int getValue() { return value.get(); } /** * 尝试设置新数值. */ public boolean trySetValue(int expectedValue, int newValue) { while (true) { int currentValue = this.value.get(); if (currentValue != expectedValue) { return false; } else { if (this.value.compareAndSet(currentValue, newValue)) { return true; } } } } } ``` 在这个案例里,`trySetValue()` 方法试图仅当现有值等于预期旧值时才应用新的变更。这正是CAS(compare-and-swap)算法的核心思想之一,也是许多现代CPU架构所原生支持的一种低级机器码级别上的优化措施。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

shangjg3

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值