多线程中常见的锁策略

目录

前言

一、乐观锁和悲观锁

二、轻量级锁和重量级锁

三、自旋锁和挂起等待锁

四、读写锁和互斥锁

五、公平锁和非公平锁

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


前言

锁策略主要是给锁的设计人员所进行参考,但是对于我们这些使用者而言,了解一些主要的锁策略可以帮助我们更正确地使用锁。锁策略在任何涉及到锁的相关知识都适用,并没有语言上的区分。

一、乐观锁和悲观锁

此处的" 乐观和悲观 "是针对于发生锁冲突概率而言;

如果发生锁冲突的概率比较小,那么就是乐观锁;

如果发生锁冲突的概率比较大,那么就是悲观锁。

对于乐观锁而言,由于发生锁冲突的概率较小,因此后续所需要做的工作也就更少,而悲观锁则反之。

二、轻量级锁和重量级锁

轻量级锁,其加锁的开销比较小,如消耗时间比较少、占用资源比较少等;

重量级锁,则加锁开销比较大,如消耗时间较多,占用资源较多。

这对锁策略和乐观悲观锁在概率上有着一定的重合:

由于轻量级开销较小,势必是因为所需工作较少,因此一个轻量级锁也很可能是一个乐观锁;

而重量级锁由于开销较大,那么所需工作肯定较多,因此一个重量级锁很可能是一个悲观锁。

但也只是存在一定的重合,并不绝对。以上两对锁策略更像是站在不同的角度来看待问题。乐观悲观锁是站在锁冲突概率的角度,考虑的是加锁之前的问题。而轻量级和重量级锁则是站在加锁的开销角度,考虑的是加锁之后的问题。

三、自旋锁和挂起等待锁

自旋锁是轻量级锁的一种典型实现,是在用户态下,使用自旋的方式来实现,例如使用 while 循环,不断地对锁的状态进行判断,目的是为了在锁释放后的第一时间内拿到该锁,进行加锁。

而挂起等待锁则是重量级锁的一种典型实现,当发现锁已经被占用了的时候,就由内核调度该线程挂起,也即是进入阻塞等待状态,到后续一定时间后再进行对锁状态的判断。

举一个鲜明的例子:

就好比追妹子,自旋锁就像一个死皮赖脸的舔狗一般,每天都会对已经有了男朋友的女神嘘寒问暖,早安午安晚安,为的就是能在女神分手后的第一时间趁虚而入,捕获女神的芳心;

而挂起等待锁,就不像自旋锁那么舔,像一个追求者,在得知女神已经有了男朋友了之后,也就不再打扰对方,而是干自己的事情去,等到偶然得知女神分手了之后,再次出击发起进攻。

那么就很容易发现,舔狗的方式虽然比较耗费精力一些,但是可以以最快的速度在女神分手之后就发起攻击。普通追求者的方式虽然知道消息的速度没那么快,但是就没那么耗费时间和精力。

因此,类比到锁策略上也是如此,自旋锁由于一直发起" 询问 ",因此获取到锁的速度最快,但是就比较耗费 cpu 资源,挂起等待锁就相反,虽然消耗的 cpu 资源比较少,但也就无法保证第一时间拿到锁。

四、读写锁和互斥锁

互斥锁就是普通的锁,如 synchronized;

读写锁,是一种读数据和写数据分别加锁的锁,也即是把读操作加锁和写操作加锁分开了。

这么分开就有一个好处:

由于多线程中,多个线程同时读取同一个数据,并不会造成线程安全问题,因此读写锁就有以下设定:

1)如果两个线程,一个读加锁,另一个也读加锁,不会产生锁竞争;

2)如果两个线程,一个读加锁,另一个写加锁,会产生锁竞争;

3)如果两个线程,一个写加锁,另一个也是写加锁,会产生锁竞争。

一般的锁,是读写一起加锁,就会导致两个线程同时读的时候,也会产生锁竞争。这一个小小的区别,就会很大程度影响到程序的效率,因为在日常使用中,读操作是一个很频繁进行的操作,而如果每次都产生锁竞争,阻塞等待的时间就会很影响效率。

五、公平锁和非公平锁

此处的公平和不公平是针对于锁释放之后,是否按照等待的先后顺序来竞争锁。

当锁释放之后,如果按照阻塞等待的先后顺序,让先进入阻塞等待的线程先获得锁,那么就是公平锁;如果锁释放之后,所有线程都有一样的概率来竞争锁,那么则为非公平锁。通俗点讲,就是遵守先来后到的是公平锁,否则则为非公平锁。

举个栗子:

还是那个追求者们心心念念的女神,如果女神分手之后,已经早早等候在她身边的舔狗可以得到女神的认可,那么就相当于给女神" 加锁 ",就是公平锁;

如果是女神说:所有追求者公平竞争,那么就是非公平锁。

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

可重入锁是指:一个线程,针对同一把锁,连续加锁两次,产生了死锁,那么就是不可重入锁,如果不会产生死锁,那么就是可重入锁。

可重入锁内部,会记录当前是哪个线程持有了该锁,因此当该锁连续加锁两次时,就能判别出是已经持有该锁的线程再次加锁,因此就不会产生死锁。

并且,还有记录持有该锁的线程加了几次锁的" 计数器 ",当该线程加锁时,计数器就 +1,释放锁就 -1,这样就方便了后续解锁的时候,判别什么时候才应该真正的解锁。

下面就是可重入锁的示意图( synchronized 本身就是一个可重入锁 ):

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值