线程如果锁住了某个资源,致使其他线程无法访问的这种锁被称为悲观锁,相反,线程不锁住资源的锁被称为乐观锁
CAS、自旋锁都是乐观锁的一种实现
private AtomicInteger count = new AtomicInteger(0);
public void syncMethod(){
boolean swapSuccess = false;
for(int i=0; i<10; i++){
int oldVal = count.get();
int newVal = old + 1;
swapSuccess = flag.compareAndSet(oldVal, newVal);
if(swapSuccess){
break;
}
}
System.out.println("替换成功标记:" + swapSuccess);
}
乐观锁的本质,通过条件判断来决定是否执行操作
ABA 问题解决:
乐观锁的实现:版本号、时间戳
- 获取数据
- 修改数据
- 提交前进行版本检测,版本无变化则提交成功
- 提交失败则重复步骤1
悲观锁
synchronized、lock,不管是否存在竞态条件,都会加锁
数据库乐观锁
- 先查询数据
- 对数据进行修改
- update 的时候 where 条件里需要带版本号,且 update 需要对版本号进行修改
- 返回受影响的行数,通过行数判断是否修改成功
- 如果未修改成功重复步骤1