面试官最爱问的Java锁策略,90%的人答不全!

在这里插入图片描述

🔍 开发者资源导航 🔍
🏷️ 博客主页个人主页
📚 专栏订阅JavaEE全栈专栏

锁策略

如果你自己需要实现一把锁(你认为标准库给你的锁不够用)你需要关注锁策略,其实大多数情况synchronized已经足够用了,但是java面试中常常会考QwQ。

所谓锁策略,就是在加锁的时候有什么特点,有什么行为。

常见的锁策略有六种:

  1. 悲观锁/乐观锁
  2. 重量级锁/轻量锁
  3. 挂起等待锁/自旋锁
  4. 互斥锁/读写锁
  5. 可重入锁/不可重入锁
  6. 公平锁/非公平锁

1. 悲观锁/乐观锁

如果我们预测,线程尝试获取一个锁的时候,获取频率很低,这种情况一般称其为乐观情况,反之称其为悲观。

乐观锁:加锁的时候,预测接下来的竞争不激烈,获取频率较高不需要做额外工作,例如让两个线程去竞争一个锁。
悲观锁:加锁的时候,预测接下来的竞争非常激烈,获取频率较低需要针对这样的情况做额外工作,例如100个线程去竞争一个锁。

乐观锁在遇到竞争时,可以即使获取到锁,悲观锁在遇到竞争时获取的概率较低。

2.重量级锁/轻量锁

重量级锁和轻量级锁是对于悲观和乐观场景的解决方案。

重量级锁:在悲观场景下要付出更多的代价,更低效
轻量锁:在乐观场景下要付出更少的代价,更高效

3.挂起等待锁/自旋锁

挂起等待锁/自旋锁是重量级锁/轻量锁的典型具体实现方法。

自旋锁:获取锁的周期更短,在等待时会采取忙等的方法,能够及时获取到锁,这个过程一直消耗cpu。

重量级锁:获取锁的周期更长,在遇到竞争时,会进入阻塞状态等待内核唤醒,因此很难做到及时获取,但是这个过程不必一直消耗cpu,把cpu省下来干别的事情。

4.互斥锁/读写锁

互斥锁:在一个线程已经获取到锁的情况下,其他的任何线程尝试获取时都会产生互斥。

读写锁

读写锁对于读多写少的情况进行了优化。

在这种情况下读和读会产生线程安全吗?显然是不会的,只有在涉及到读写的情况才会产生线程安全。

因此我们在读读时不需要进行互斥,而涉及到读写时会产生互斥。

而这就是读写锁的特点:

  1. 读读共享:多个读线程可以同时获取读锁

  2. 读写互斥:读锁和写锁不能同时持有

  3. 写写互斥:同一时间只能有一个线程持有写锁

  4. 可重入性:线程可以重复获取已经持有的锁

5.可重入锁/不可重入锁

可重入锁:线程可以重复获取已经持有的锁。
不可重入锁:线程不可以重复获取已经持有的锁。

典型的就是常用的synchronized,它就是一个可重入锁,在此种情况下就不会陷入死锁状态。

synchronized(locker) {
	//...
	synchronized(locker) {
	//...
	}
}

6.公平锁/非公平锁

公平锁:遵循时间的先来后到。

非公平锁:遵循每一个线程概率相等。

在默认情况下他是非公平的状态,实现公平锁需要付出一些代价,比如说使用一个队列去记录各个线程获取锁的顺序。


感谢各位的观看Thanks♪(・ω・)ノ,如果觉得满意的话留个关注再走吧。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值