乐观锁和悲观锁的区别?
简单来说,乐观锁就是假设拿数据的都不会修改,所以读不加锁,写入的时候才加锁,去判断读取之后有没有被更新。而悲观锁是假设每次读数据都会修改,所以在读的时候就加锁,一个线程使用的时候,其它线程都阻塞。
乐观锁适合多读场景,悲观锁适合多写场景。
synchronized和ReentrantLock都是悲观锁。
乐观锁常见的实现方式?
-
版本号机制
以数据库为例,给数据一个版本号字段,需要更新的话将读出的版本号增加,然后写入时比对版本号,如果表中的版本号小于要写入的版本号,就可以写入,否则就是被其他人修改了,就不允许写入更新,需要重新读取。 -
CAS 比较与交换,无锁算法,非阻塞同步
简单来说,就是写入的时候比较目标值是否等于读出的值,如果等于就更新为新的值,否则不做任何操作,一般情况下是一个自旋操作,即不断的重试。
CAS的缺点?
- ABA问题
就是如果在读出A值后,其它线程将其修改为B,又修改回A,那么会被误认为未修改而直接更新。 - 循环时间长开销大
自旋CAS(也就是不成功就一直循环执行直到成功)如果长时间不成功,会给CPU带来非常大的执行开销。 - 只能保证一个共享变量的原子操作
CAS 只对单个共享变量有效,当操作涉及跨多个共享变量时 CAS 无效。
CAS与synchronized的使用情景?
简单的来说CAS适用于写比较少的情况下(多读场景,冲突一般较少),synchronized适用于写比较多的情况下(多写场景,冲突一般较多)。
暂无评论