常见的锁策略

目录

一、乐观锁和悲观锁

二、读写锁和普通互斥锁

三、轻量级锁和重量级锁

四、自旋锁和挂起等待锁

五、公平锁和非公共平锁

六、可重入锁和不可重入锁


一、乐观锁和悲观锁

乐观锁:预测锁冲突的概率较低,多个线程在访问锁对象时不会真的加锁,代码中需要做的工作量比较少。

悲观锁:预测锁冲突的概率较高,多个线程在访问锁对象时都会进行真加锁,代码中需要做更多的工作。

举个栗子:

        假设有两对情侣:男一号和女一号,男二号和女二号。

        乐观锁:男一号认为自己和女一号感情非常好,女一号不会和其他男生搞暧昧,所以偶尔才会问一下女一号:“你爱我吗?”

        悲观锁:男二号总是害怕女二号会绿他,即使在他们感情非常好的时候,他都要每天问女二号:“你爱我吗?”

二、读写锁和普通互斥锁

普通互斥锁:多个线程竞争同一把锁时,当一个线程竞争到锁之后,其他线程就阻塞等待。比如synchronized

读写锁分为两种情况:

加读锁:多个线程同时读一份数据时,不会有线程不安全的问题,所以没必要加锁。

加写锁:多个线程同时写一份数据,或者有的线程写有的线程读同一份数据时,会有竞争,也就会有线程不安全问题,此时需要加锁。

实际开发中,的场景一般会多于的场景,所以使用读写锁就会减少很多锁竞争的情况,优化程序的效率。

三、轻量级锁和重量级锁

轻量级锁:加锁、解锁的开销比较小。

        纯用户态的加锁逻辑,不涉及到进入内核的操作,因此开销比较小。

重量级锁:加锁、解锁的开销比较大。

        需要进入内核态的加锁逻辑,开销就比较大。

注意:

轻量级锁和重量级锁是站在加锁解锁的结果来进行区分:

重量级锁:加锁、解锁操作消耗的时间多。

轻量级锁:加锁、解锁操作消耗的时间少。

乐观锁和悲观锁是站在加锁的过程来进行区分:

乐观锁:加锁的过程中需要做的工作比较少。

悲观锁:加锁的过程中需要做的工作比较多。

因此,乐观锁一般也是轻量级锁,悲观锁一般也是重量级锁,但这个结论并不绝对~

四、自旋锁和挂起等待锁

自旋锁:线程A和线程B竞争同一把锁,线程A竞争到之后,线程B会立刻尝试重新获取锁,无限循环,直到获取到锁为止。所以只要锁被线程A释放,线程B就会第一时间获取到锁,但是这样会消耗大量的CPU资源。自旋锁是纯用户态实现的。

挂起等待锁:线程A和线程B竞争同一把锁,线程A竞争到之后,线程B进行阻塞等待,此时CPU就会空出来可以做其他的工作,但线程B获取到锁的时机可能并不会很及时。

举个栗子:

        假设男生A约女生B一起吃饭,男生A早早来到餐厅等待~

        自旋锁:男生A会不停地打电话问女生B:“你到了吗?”当女生B到餐厅时,男生A就会立刻知道。

        挂起等待锁:男生A到餐厅后打个电话问女生B:“你到了吗?”女生B说:“还没有~”

于是男生A就拿出手机刷视频,打游戏……所以当女生B到达餐厅时,男生A并不一定能及时知道。

自旋锁适用于锁持有时间比较短的场景,更高效。如果锁的持有时间比较长,就会浪费CPU资源。

挂起等待锁则适用于锁持有时间比较长的场景,可以合理利用CPU资源。 

五、公平锁和非公共平锁

公平锁:多个线程竞争同一个锁对象时,会遵循先来后到的规则。

非公平锁:多个线程竞争同一个锁对象时,不遵循先来后到,而是谁抢到就是谁的。

操作系统默认的锁的调度是非公平锁,要想实现公平锁,需要引入额外的数据结构来记录每个线程加锁的顺序,所以也需要花费额外的开销。

举个栗子:

        假设有一群人都在等同一辆公交车~

        公平锁:所有人都自觉地排队上车,先来的排在前面,后来的排在后面。

        非公平锁:一群人都不讲武德,挤着上车。

六、可重入锁和不可重入锁

可重入锁:一个线程连续加锁两次,不会出现死锁的问题,比如synchronized

        synchronized会记录当前持有锁的线程,如果发现当前线程在释放锁之前再次进行加锁,就会让计数器自增,线程解锁,则计数器自减,当计数器为0时进行解锁操作,线程才会真正释放锁。

不可重入锁:一个线程连续加锁两次,会出现死锁的问题。

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

吃点橘子

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值