首页 > 编程知识 正文

悲观锁和乐观区别简答,hashmap底层实现原理

时间:2023-05-03 21:54:28 阅读:34504 作者:3102

什么是悲观锁,什么是乐观锁?

悲观锁定:时尚烧鹅是悲观的,对程序进行锁定处理,一次只能有一个线程操作,以确保线程的安全。

乐观锁定:时尚烧鹅是乐观的,乐观锁定并未真正锁定,通过程序控制保证线程的安全。悲观锁和乐观锁对比

比较:

悲观锁定是重量级锁定,乐观锁定是轻量级锁定。

悲观锁定效率低,乐观锁定效率高。

悲观锁定通过实际锁定来控制程序的执行,乐观锁定通过程序控制来保证线程的安全。悲观锁原理

悲观锁定是一种重量锁定,通过锁定程序来保证线程的安全性。 例如,我们常用的同步、返回锁定等是高并发的,当多个线程进入程序时,谁获得锁定,谁运行程序,未获得锁定的线程继续等待。乐观锁原理

乐观锁定是轻型锁定。 像CAS自由锁定机制那样,通过程序控制来保证线程的安全性,在高速同时执行中,多个线程进入程序时,可以比较原始值和原始期待值,或者通过版本号进行控制,只有一个线程可以执行程序,可以3358 www.Sina.com/http://www.Sina.com/: synchronized是一种重量锁,jdk1.6之前,synchronized的效率特别低,主要是多个线程同时访问如果其他线程等待锁定的线程从运行状态切换到阻止状态,然后切换到准备状态,则状态切换会降低效率。 因为线程进入就绪状态时,再次进入运行状态需要调度cpu,从而增加开销。 从JDK 1.6版开始,oracle优化了同步并增加了临时旋转。 也就是说,同时访问时线程获得了锁定。 其他线程将进入临时自旋重试状态,而不是直接切换状态。 如果当前获取锁定的线程立即解锁,则其他线程可以直接获取和执行锁定,而不是直接在状态之间切换以等待cpu调度,从而减少了时间和资源开销。以synchronized和CAS为例进行分析:CAS是轻型锁定,程序未锁定。 CAS中包含3个参数,存储器值v。 此值由所有线程共享,可以理解为该值包含volatile限定、原始期望值a、新值b和名词。 让我简单说明一下。 例如,内存中原始期望值a也为1,新值为6。 CAS的原理是比较v和a的值是否相等。 相等时修正,否则不修正。 CAS并不是实际锁定的,因此并发时,其他线程也可以操作该值。 举个例子,现在有线程1和线程2,线程1加5,线程2减3。 首先,允许两个线程同时访问。 A=1,B=6,线程1还未被操作时,cpu时间片被线程2夺走,线程2得到V=1,A=1,B=-2,线程2得到v的值,判断为v是a,所以此时v 如果线程1确定v为a时注意到v为-,请修改A=-2,B=3,然后确定V==A,并将此值修改为3。 可以看到同一时间只有一个线程在操作这个值。 线程的安全性之所以得到保证,是因为在修改此值之前必须确定v和a是否相等。 不相等的话就不能操作。 否则,继续循环。

synchronized

悲观锁定:效率低,重量级锁定,独家锁定。

乐观锁定:可能会出现ABA问题和循环开销问题。CAS

ABA问题是指,如果线程1取得该值并设为a,则v=‘a’、a=‘a’,

线程2如果更改此值并等于b,则v=‘b’、

线程3如果将此值更改为a,则v=‘a’、

此时,线程1确定v等于原始期望值a并进行修改,但是线程1不能感知到该值从a变为b变为a。 这就是ABA的问题。 只进行数值操作当然没有问题,但是库存操作怎么样? 库存数量不变,但中途经过出库和入库操作,性质可能发生了变化。悲观锁和乐观锁各自的缺点

由于版本号在每次操作时增加,因此增加版本号的控制部不仅判断V=A,还判断版本号是否相等,就能够确认值是否被修正

示例:

如果线程1将该值设为a,版本号设为1,则v=‘a’、a=‘a’、Version=1,

线程2如果将此值更改为b,则v=‘b’、Version=2、

线程3如果将此值更改为a,则v=‘a’,Version=3。

此时,线程1发现v等于原始期望值a,但版本号不相等,因此重新获取值,判定为v=‘a’、a=‘a’、Version=3,如果V==A同时版本号也相等,则继续进行循环判定ABA:

综上所述,如果VA,则再次取得值并继续进行循环判定,但如果线程数特别多,则循环开销变大,占用cpu,有可能在短时间内cpu使用率变高。

版权声明:该文观点仅代表作者本人。处理文章:请发送邮件至 三1五14八八95#扣扣.com 举报,一经查实,本站将立刻删除。