悲观锁与乐观锁笔记

观看视频。根据以下视屏,写的笔记

【Java并发】面试官问我CAS、乐观锁、悲观锁,我反手就是骑脸输出_哔哩哔哩_bilibili

悲观锁

假设现在有多个线程想要操作同一个资源对象

很多人的第一反应就是使用互斥锁,但是互斥锁的同步方式是悲观的。

什么是悲观呢

简单来说操作系统将会悲观的认为,如果不严格同步线程调用,那么一定会产生异常。所以互斥锁将会将资源锁定,只供一个线程调用,而阻塞其他线程,因此这种同步机制也叫悲观锁。但是悲观锁不是万能的。

比如在一些情况下,大部分调用可能都是读操作,那么就没有必要在每次调用的时候都锁定资源;或者在一些情况下,同步代码块执行的耗时远远小于线程切换的耗时,那么使用这种锁就有些本末倒置了。所以在这种情况下,我们不想操作系统这么悲观,我们不想过度使用互斥锁。

乐观锁

在我们的设想中能不能不对共享资源锁定也能对线程调用进行协调?

因此诞生一种非常经典和巧妙的算法叫CAS(compare and swap)

当资源对象的状态值为0的一瞬间,AB两条线程都读到了,此时这两条线程认为资源对象当前的状态值是0,于是他们就会各自产生两个值old value 代表之前读到的资源对象的状态值,new value代表想要将资源对象的状态值更新后的值。这里对两条线程来说old value都是0,new value都是1。

此时AB线程争抢着去修改资源对象的状态值,然后占用他。假设a线程率先获得时间片,他将old value 与资源对象的状态值进行compare(比较)发现一致。于是将牌子上面的值swap(交换)为new value。而b线程因为落后了一步,资源状态的值被a线程修改为1,b线程在compare的时候发现值与自己预期的old value不一致,所以放弃swap操作。但实际应用中,我们不会让b线程直接放弃。通常会使其自旋(不断重复CAS操作)通常会配置自旋次数防止死循环。

CAS必须是原子性的,各种不同架构的CPU都提供了指令级别的CAS原子操作。也就是不需要通过操作系统的同步原语CPU已经原生的支持 CAS,上层进行调用即可,这样我们就能不再依赖锁来实现线程同步。但这并不意味着无锁能够完全代替有锁。

这些通过CAS来实现同步的工具,由于不会锁定资源,而且当线程需要修改共享资源的对象式时,总是会乐观的认为对象状态值没有被其他线程修改过,而是每次自己会主动尝试去compare状态值。相较于上文提到的悲观锁,这种同步机制被称为乐观锁。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值