Java-悲观锁与乐观锁

悲观锁

每次都认为用数据的同时,别人可能会修改,因此每次拿数据的同时都要加上锁,因而降低了性能。

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)每次只能保证一个共享变量。解决办法:可以把多个共享变量合并起来

posted @ 2019-04-25 20:06  注册以后还能改吧  阅读(121)  评论(0编辑  收藏  举报