社招面试翻车记:面试官让我聊聊 ReentrantLock

18 阅读4分钟



“你知道 Java 里的可重入锁(ReentrantLock)吗?”

听到这个问题的瞬间,我脑子一懵,感觉整个人都不好了。

这可是社招面试啊!面试官可不是在跟你闹着玩,这要是答不上来,我这 10K+ 的大厂 offer 可就凉凉了。

我硬着头皮回忆,嘴里下意识冒出一句:“额……ReentrantLock 是一个可重入的互斥锁,提供了比 synchronized 更灵活的控制方式。”

“能详细说说吗?比如它的实现原理、和 synchronized 的区别、应用场景等等?”

完蛋!面试官竟然“上套”了,一看就是准备把这个问题往深了挖。

今天,我就跟大家好好复盘一下,ReentrantLock 到底是个啥,以及在面试里应该怎么回答才能让面试官眼前一亮!

什么是可重入锁?

1. 先聊聊“可重入”这个概念

咱们先不谈 ReentrantLock,单纯想象这么个场景:

你家有个门,锁是你自己装的,钥匙也只有你一个人有。你打开门进了屋,突然发现自己忘了拿手机,于是你又转身开门进去拿。

此时,你仍然在“家”里,对吧?你并不需要重新申请钥匙,因为你已经有了访问权限。

同理,在 Java 里, “可重入”意味着同一个线程在持有某把锁的时候,可以再次获取这把锁,而不会导致自己被阻塞。”

2. synchronized 其实也是可重入的

运行结果:

解析:

  • methodA() 持有锁,methodB() 也是 synchronized 的,但并不会阻塞自己,而是可以正常执行。
  • 这就是可重入性,如果 synchronized 不是可重入的,那么 methodA() 进入后调用 methodB() 会被自己锁住,导致死锁。

3. ReentrantLock 是个啥?

synchronized 既然已经可重入了,那为什么还要 ReentrantLock 呢?

因为 synchronized 虽然简单易用,但它的功能有限,比如:

  • 无法尝试获取锁(想要获取锁但不阻塞等待)
  • 无法中断等待(线程等待锁时无法响应中断)
  • 无法实现超时获取锁(避免无限等待)
  • 无法公平加锁(锁的获取没有 FIFO 规则)

于是,JDK 提供了 java.util.concurrent.locks.ReentrantLock,它是 synchronized 的增强版,提供了更灵活的锁机制。

ReentrantLock 的核心功能

1. 基本使用

输出(执行顺序可能不同):

解析:

  • lock.lock() 获取锁,如果锁已经被占用,会等待。
  • lock.unlock() 释放锁,防止死锁。
  • finally 确保锁一定会被释放(必须养成好习惯)。

2. 可重入性

ReentrantLock 当然也是可重入的,否则它就不配叫 ReentrantLock 了:

  • 一个线程持有锁时,可以再次获取该锁,而不会被阻塞!
  • 每 lock() 一次,就需要 unlock() 一次,否则锁不会释放。

ReentrantLock vs synchronized

面试中如何回答?

面试官一般会问:

  • 什么是可重入锁?
  • synchronized 是可重入的吗?
  • ReentrantLock 和 synchronized 的区别?
  • ReentrantLock 的应用场景?

标准回答:

可重入锁指的是同一个线程在获取锁后,可以再次获取同一把锁,而不会被阻塞。synchronized 和 ReentrantLock 都是可重入的,但 ReentrantLock 相比 synchronized 提供了更多的特性,比如支持公平锁、可中断锁、超时获取锁等。ReentrantLock 适用于高并发场景,比如数据库连接池、任务调度等,而 synchronized 适合简单的同步需求。

加分项:

ReentrantLock 是基于 AQS(AbstractQueuedSynchronizer)实现的,通过 CLH 队列来管理锁的获取顺序,并提供可中断锁、超时等待锁等特性,使得线程调度更高效。

总结

  • 可重入锁:同一个线程可以多次获取同一把锁。
  • ReentrantLock 是 synchronized 的增强版,提供更灵活的锁机制。
  • 使用场景
    • synchronized 适合简单同步,代码简洁。
    • ReentrantLock 适用于高并发场景,比如数据库、任务调度等。
  • 面试要点
    • 说清可重入的概念。
    • 结合 synchronized 进行对比。
    • 提及 ReentrantLock 的特性和应用场景。

END

如果你在面试中遇到这个问题,现在你已经胸有成竹了!

我是小米,一个喜欢分享技术的31岁程序员。如果你喜欢我的文章,欢迎关注我的微信公众号“软件求生”,获取更多技术干货!