什么是乐观锁?

乐观锁是一种基于“无锁”思想的并发控制机制。它假设多线程操作之间很少发生冲突,因此在读取数据时不会加锁,而是通过某种机制(如版本号或时间戳)来检测数据是否被其他线程修改过。如果检测到数据未被修改,则提交更新;如果检测到数据已被修改,则根据策略进行处理(如重试或抛出异常)。

乐观锁的实现方式

一种是版本号机制:为数据添加一个版本号字段,每次更新时递增版本号,并在更新时验证版本号是否匹配。

另一种是CAS 操作:使用比较并交换(Compare-And-Swap)指令,直接在硬件层面实现无锁操作。CAS 操作包含内存位置(V)、预期值(A)和新值(B)这三个参数。只有当内存位置的值等于预期值时,才会将内存位置的值更新为新值。

乐观锁的特点

第一个是无锁设计,乐观锁不依赖传统的锁机制,减少了线程阻塞和上下文切换的开销。 第二个是性能好,在低冲突场景下,乐观锁的性能优于悲观锁,因为它避免了锁的竞争。 第三个是支持冲突检测,乐观锁通过版本号或 CAS 操作检测冲突,但需要开发者显式处理冲突(如重试或回滚),这可能会增加代码的复杂性。

乐观锁的适用场景

第一种是读多写少的场景,例如缓存系统、统计计数器等,读操作远多于写操作,冲突概率较低。 第二种是在分布式环境中,乐观锁可以通过版本号或时间戳实现跨节点的数据一致性。 第三种是高并发环境,在高并发场景下,乐观锁可以减少锁的竞争,从而提高系统的吞吐量。 需要注意的是,乐观锁并不适合写操作频繁或冲突概率较高的场景,因为频繁的冲突会导致大量的重试操作,反而降低性能。