JavaEE多线程中常见的锁策略


常见的锁策略

乐观锁vs悲观锁

乐观:

预测锁冲突的概率不高,因此做的工作就可以简单一点

悲观:

预测锁冲突(两个线程竞争同一把锁,产生锁冲突,会阻塞等待)的概率较高,因此做的工作就要复杂一些

在这里插入图片描述

读写锁 VS 普通互斥锁

普通的互斥锁,就如同synchronized
当两个线程竞争同一把锁,就会产生等待

读写锁,分成两种情况

  1. 加读锁
  2. 加写锁

读锁和读锁之间,不会产生竞争~
写锁和写锁之间,有竞争~ ~
读锁和写锁之间,有竞争~ ~

读的场景往往很多,写的场景往往更少
读写锁相比于普通的互斥锁,就少了很多的锁竞争,优化了效率!
在这里插入图片描述

重量级锁 VS 轻量级锁

也是一个锁策略~

轻量级锁,加锁解锁开销比较小
重量级锁,加锁开锁解锁开销比较大

典型的,纯用户态的加锁逻辑,开销是比较小
典型的,进入内核态的加锁逻辑,开销是比较大的

重量级锁和轻量级锁是 : 站在结果的角度看待的,最终加锁解锁操作消耗的时间是多还是少

  • 乐观锁,指的是干的事情少
  • 悲观锁,指的是干的事情多

乐观锁和悲观锁是 : 站在加锁的过程中看的,加锁解锁过程中干的工作是多还是少

因此通常情况下,乐观锁,一般也比较轻量,悲观锁,一般比较重量(干的工作多,消耗的时间就多)
但是也不绝对~ ~


上述锁策略,指的都是实现锁的时候考虑的

在这里插入图片描述

自旋锁和挂起等待锁

自旋锁轻量级锁的一种典型实现(更及时,需要的时间更短,所以是轻量级锁)
挂起等待锁,是重量级锁的一种典型实现(获取锁消耗的时间更长,并且中途会做别的事,做的事更多,所以是重量级锁)

自旋就类似于 “忙等” ,消耗大量的CPU,反复询问当前的锁是否就绪~

自旋锁是纯用户态实现的,和进入内核相比的工作量还是要更少~

两种等待策略:

  1. 自旋(一直请求获取锁)
  2. 挂起等待
    挂起等待的时候,获取到的锁时间就更久(没那么及时了),但是这个时间里,CPU可以干别的!
    在这里插入图片描述

公平锁 VS 非公平锁

公平锁:
遵守先来后到”. t1,t2,t3竞争同一把锁,谁先来的,谁就先拿到锁~

非公平锁:
不遵循"先来后到",t1,t2,t3都有可能拿到锁

操作系统默认的锁的调度,是非公平的情况~

要想实现公平锁,需要引入额外的数据结构,来记录线程加锁的顺序,需要一定的额外开销

在这里插入图片描述

可重入锁VS 不可重入锁

  • 可重入锁 : 同一个线程针对同一把锁,连续加锁两次,不会死锁!
  • 不可重入锁 : 同一个线程针对同一把锁,连续加锁两次,会死锁!

JavaEE多线程中的 死锁 可重入锁和内存可见性问题

总结

在这里插入图片描述

你可以叫我哒哒呀
本篇到此结束
“莫愁千里路,自有到来风。”
我们顶峰相见!
  • 3
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 6
    评论
评论 6
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值