乐观锁与悲观锁
Posted wscy
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了乐观锁与悲观锁相关的知识,希望对你有一定的参考价值。
乐观锁与悲观锁
悲观锁
假定会发生并发冲突,屏蔽一切可能违反数据完整性的操作。如,synchronized
关键字使用。
乐观锁
假设不会发生并发冲突,只在提交操作时检查是否违反数据完整性。如,CAS(Compare and Swap 比较并交换)。
- 获得锁后一直持有锁,以防本线程再次申请该锁造成无谓的解锁再加锁开销。
- 假设没有冲突而去完成同步代码块,如果冲突再循环重试。
- 采取申请锁失败后不立刻挂起而是稍微等待再次尝试获取,以减少线程因为挂起、阻塞、唤醒而造成的开销。
CAS介绍
CAS 操作中包含三个操作数
- 需要读写的内存值
- 进行比较的预期值
- 拟写入的新值
原理
当且仅当预期值和内存值相等时才将内存值修改为新值。首先检查某块内存的值是否跟之前读取时的一样,如不一样则表示期间此内存值已经被别的线程更改过,舍弃本次操作;否则说明期间没有其他线程对此内存值操作,可以把新值设置给此块内存。
问题
只能保证一个共享变量的原子操作
JDK提供了
AtomicReference
类来保证引用对象之间的原子性,可以把多个变量放在一个对象里来进行CAS操作。循环时间长、开销大
自旋CAS(不成功,就一直循环执行,直到成功)。
ABA问题
内存值原来是A,后来被一条线程改为B,最后又被改成了A。
解决方法:引入版本号,更新变量同时修改版本号。
以上是关于乐观锁与悲观锁的主要内容,如果未能解决你的问题,请参考以下文章