乐观锁和悲观锁

乐观锁:

总是假设最好情况,认为修改数据过程中该数据不会被其他进程修改,不加锁。

在修改数据时判断该数据是否被更改,可通过版本号(version)和CAS(compare and swap)实现。

在Java中java.util.concurrent.atomic包下面的原子变量类就是使用了乐观锁的一种实现方式CAS实现的。

悲观锁

总是假设最坏情况,认为处理数据过程中该数据会被其他进程修改,加锁阻塞。

处理数据过程:获取锁-》修改数据-》释放锁

传统的关系型数据库里边就用到了很多这种锁机制,比如行锁,表锁等,读锁,写锁等,都是在做操作之前先上锁。Java中synchronizedReentrantLock等独占锁就是悲观锁思想的实现。

使用场景:

乐观锁适用于写比较少的情况下。多写的场景下用悲观锁就比较合适。

很少发生冲突时使用乐观锁,省去锁的开销,增加吞吐量。写多的情况下使用乐观锁,经常产生冲突,不断重试,会降低性能。

乐观锁的缺点:

1 ABA 问题

如果一个变量V初次读取的时候是A值,并且在准备赋值的时候检查到它仍然是A值,那我们就能说明它的值没有被其他线程修改过了吗?很明显是不能的,因为在这段时间它的值可能被改为其他值,然后又改回A,那CAS操作就会误认为它从来没有被修改过。这个问题被称为CAS操作的 "ABA"问题。

2 循环时间长开销大

自旋CAS(也就是不成功就一直循环执行直到成功)如果长时间不成功,会给CPU带来非常大的执行开销。

3 只能保证一个共享变量的原子操作

https://www.cnblogs.com/qjjazry/p/6581568.html

原文地址:https://www.cnblogs.com/cnsec/p/13547569.html