线程安全的锁策略,你到底忽略了多少?
文章目录
- 线程安全的锁策略,你到底忽略了多少?
- 一,🔰乐观锁vs悲观锁
- 二,📍轻量级锁 vs 重量级锁
- 三,📍自旋锁 vs 挂起等待锁
- 四,📍互斥锁 vs 读写锁
- 五,📍可重入锁 vs 不可重入锁
- 六,📍公平锁 vs 非公平锁
一,🔰乐观锁vs悲观锁
锁的实现者,预测接下来锁冲突的概率高还是低,根据冲突概率,来进行相应的操作。
乐观锁🔒:预测冲突概率较小,对锁冲突保持积极态度
悲观锁🔒:预测冲突概率较大,对锁冲突保持消极态度
二,📍轻量级锁 vs 重量级锁
轻量级锁🔒:加锁解锁更快更加高效
重量级锁🔒:加锁解锁非常慢十分低效
三,📍自旋锁 vs 挂起等待锁
自旋锁🔒:(轻量级锁)在解锁后,自旋锁会不停歇的寻找下一个锁,自旋锁是一种纯用户态的锁,因为是轻量级锁,所以消耗的资源少,不过长时间寻找锁也会导致CPU消耗,而且在寻找锁时是不能做其他任务的。
- 速度快,可以第一时间拿到锁,消耗CPU资源(忙等)
挂起等待锁🔒:(重量级锁)在解锁后,挂起等待锁会自动放弃等待时机,相当于挂起等待锁不会去一直等待锁,而是需要锁时,而且锁是空闲状态,才会进行加锁,自旋锁是一种内核态的锁,因为是重量级锁,所以消耗的资源多。
- 锁被释放,无法第一时间拿到锁,不消耗CPU资源
四,📍互斥锁 vs 读写锁
互斥锁🔒:进入锁加锁,出锁则解锁
读写锁🔒:锁如其名,对数据的读加锁,对数据的写加锁,然后再进行完操作后,解锁。
两把锁之间的约定读数据时无竞争,写数据存在竞争,读写数据也存在竞争。
五,📍可重入锁 vs 不可重入锁
可重入锁🔒:一把锁,针对一个线程加锁两次,该线程满足不死锁的条件时,就叫做可重入锁。
不可重入锁🔒:只能加锁一次,如果对其再加锁会造成死锁(阻塞)。第一个锁释放的条件是要求第二个锁加锁,意识就是,a被锁了,要解开a,必须把a的外层进行加锁,不过这种现象几乎就是死锁了。
synchronized是一个可重入锁,在执行加锁操作时,会先判定是否会造成死锁,也就是对其线程判定一下是否在此之前已经加锁,如果已经加锁,会进行解锁,同一线程的加锁操作,直接‘放行’。
六,📍公平锁 vs 非公平锁
遵守先来先执行的锁是公平锁,反之就是非公平锁。
公平锁🔒:先来后到
非公平锁🔒:后来先到
在系统中对线程的调度是随机的,synchronized是一个非公平锁,如果需要实现一个公平锁,需要对锁中加入一个队列来记录加锁程序的顺序。
总结:synchronized可以是乐观锁,也可以是悲观锁,也可能是轻量级 (自旋锁),也可以是重量级(挂起等待锁),synchronized是一个可重入锁,synchronized是一个非公平锁。