当年被面试官连环追问 Java 锁的那 15 分钟
2026 年金三银四又到了,最近帮团队面了不少 Java 候选人,发现一个老问题还是普遍存在 —— 大多人只停留在 API 层面,稍微往深了挖就断片。
这让我想起 10 年前,我去广州 YY 面试的场景,那天面试官上来连自我介绍都没让我做,直接盯住 Java 锁这块一路追问,那 15 分钟现在还记得清清楚楚。
第一问就直接来:synchronized 是干嘛用的?
我当时回答:它能让没拿到锁的线程排队,只有拿到锁的线程才能执行,解决并发问题。现在看这个回答只能打 60 分,说清楚了作用,但没点出本质。
面试官听完立刻追了第二问:你说获取不到锁会排队,这里排队是什么意思?具体发生了什么?
我想了下回答:获取不到锁的线程会被操作系统挂起,等着拿到锁的线程释放后再唤醒。
面试官继续第三问:被挂起会很影响性能啊,有没有办法让获取不到锁的线程先不要挂起?
我当时就愣了 —— 还有这种操作?我盯着白板想了 30 秒,老实说:这个知识点我不清楚。
出来之后我才反应过来,这问的是自旋锁。思路其实很简单:如果拿不到锁,先不忙挂起,让线程原地 "自旋" 几圈等等看 —— 因为很多时候,持有锁的线程执行很快,马上就释放锁了。要是这时候还走操作系统挂起再唤醒,那上下文切换的代价反而不划算。特定场景下用自旋,效率确实提升不少。
这里我也停一下,考一考正在准备面试的你:纯自旋就一定好吗?有没有更好的改进方式?
......(思考几秒钟)
其实方案很 straightforward:自适应自旋。让线程自旋,但设置一个时间或次数阈值,如果自旋到阈值还拿不到锁,再退化成操作系统挂起。这样兼顾了性能和线程资源浪费问题,JDK 后期的 synchronized 就是这么优化的。
你以为这就完了?关于 synchronized 的追问才到一半,面试官根本没打算放过我。
继续问:synchronized 底层是怎么实现的?
还好这个知识点我之前啃过,能接上:就是通过对象头关联的 Monitor 监视器锁,字节码里用 monitorenter 和 monitorexit 两个指令标记同步块,拿到监视器锁才能进入执行,执行完调用 monitorexit 释放锁,再通知等待的线程唤醒。
嗯,这个回答过关了。那再来最后一问:除了 synchronized,Java 还有什么方式加锁?它们有什么区别?
这个问题我当时答得不好,只说了 Lock 接口,能手动加锁解锁,但没答出核心区别。其实这个问题本质是问 Java 1.5 之后 concurrent 包下的 Lock 和 synchronized 的设计差异:
- Lock 支持中断响应,synchronized 不行
- Lock 支持超时获取锁,死等不如超时放弃
- Lock 可以实现公平锁,synchronized 只能是非公平
- Lock 需要手动释放,synchronized 由 JVM 自动释放
所以整体来说,Lock 更灵活,synchronized 更易用。问到这里,面试官才终于放过我。
现在一线互联网公司的面试,就是这个路数 —— 同一个知识点层层往下挖,一直挖到你说 "我不知道" 为止。这样才能真正看出来你对这个问题理解到什么程度。
我做了十年技术面试官,负责任地说一句:如果你发现面试官每个问题只问一次就不再往下追了,那这才是危险信号 —— 说明面试官已经判断,你对这个问题也就了解这么多了,再挖也挖不出东西,没必要浪费时间。
结合现在的面试趋势,我整理了一套应对深度追问的准备方法上传到AI了,学会利用 AI 工具刻意练习:https://muyulab.com/?utm_source=csdn
更多推荐




所有评论(0)