悲观锁和乐光锁
乐观锁:对数据操作的时候不担心数据被修改,不上锁,每次修改数据的时候要根据数据进行判断是否被修改过. 适合用于db读大于写的场景
悲观锁: 自己操作数据的时候就会对数据上锁,防止自己操作的时候别人也动. 场景:在db读取大的时候,如果有线程修改操作上锁 就会被全部挂起,等修改完成释放锁才能读到数据,所以适合用于db写大于读的情况
这个写的不错
https://www.jianshu.com/p/ae25eb3cfb5d
乐观锁常见的两种实现方式
乐观锁一般会使用版本号机制或CAS算法实现。
1. 版本号机制
一般是在数据表中加上一个数据版本号version字段,表示数据被修改的次数,当数据被修改时,version值会加一。当线程A要更新数据值时,在读取数据的同时也会读取version值,在提交更新时,若刚才读取到的version值为当前数据库中的version值相等时才更新,否则重试更新操作,直到更新成功。
2 CAS
- 需要读写的内存值 V
- 进行比较的值 A
- 拟写入的新值 B
当且仅当 V 的值等于 A时,CAS通过原子方式用新值B来更新V的值,否则不会执行任何操作(比较和替换是一个原子操作)。一般情况下是一个自旋操作,即不断的重试。
乐观锁的缺点
1 ABA 问题
如果一个变量V初次读取的时候是A值,并且在准备赋值的时候检查到它仍然是A值,那我们就能说明它的值没有被其他线程修改过了吗?很明显是不能的,因为在这段时间它的值可能被改为其他值,然后又改回A,那CAS操作就会误认为它从来没有被修改过。这个问题被称为CAS操作的 "ABA"问题。
2 循环时间长开销大
3 只能保证一个共享变量的原子操作