悲观锁
每次都认为用数据的同时,别人可能会修改,因此每次拿数据的同时都要加上锁,因而降低了性能。
Java中的synchronized和ReentrantLock等就是悲观锁的思想
适用于多写的场景
乐观锁
每次都认为不会有人修改,但更新的同时回去判断在此期间是否有人去更新这个数据
Java中的java.util.concurrent.atomic。
适用于多读点应用类型,即冲突很少发生,省去了锁的开销
乐观锁的实现有版本号或者CAS算法
1.版本号
数据表上加一个版本号字段,每次更改数据时版本号都加一。操作开始时会读取版本号,提交更新时若发现版本号不一致,则重试更新操作
2.CAS(compare and swap(比较与交换))
CAS存在三个操作
(1)需要读取的内存值V
(2)进行比较的值A
(3)拟写入的新值B
只有V等于A时,CAS通过原子方式用新值B更新V,否则不断重试(自旋)。
CAS的缺点
(1)V可能已经更改成C,又更改成V了,尽管看起来没问题,但可能有潜在问题。解决办法:同时检查引用和标志是否相等
(2)可能自旋时间过长。
(3)每次只能保证一个共享变量。解决办法:可以把多个共享变量合并起来