写点什么

对线面试官 -Sychronized 和 ReentrantLock

作者:派大星
  • 2023-06-15
    辽宁
  • 本文字数:1468 字

    阅读完需:约 5 分钟

面试官: 派大星,我们今天来讨论一下 Java 中的锁机制,特别是 synchronized 和 ReentrantLock 这两个锁。首先,我想问一下,在 Java 1.5 后期(1.6 之前)的时候,synchronized 是重量级锁,后来引入了锁升级的概念。你能给我解释一下这个锁升级的过程吗?


派大星:

当然可以!在 Java 1.5 后期,引入了锁升级的概念来优化 synchronized 锁的性能。锁升级分为三个阶段:偏向锁自旋锁重量级锁

  • 首先是偏向锁阶段。偏向锁是基于对象头中的 Mark Word 来实现的,它记录了锁的标识符。在进入同步块之前,锁会先尝试加上偏向锁,标记为当前线程 ID。这样,在同一个线程多次进入同步块时,不需要重复获取锁,从而减少了性能开销。

  • 如果有其他线程尝试获取同步块的锁,就会进入自旋锁阶段。自旋锁会进行一定次数的自旋尝试,也就是忙等待,直到获取到锁或达到自旋次数上限。这样可以避免线程进入阻塞状态,减少线程切换的开销。

  • 如果自旋尝试仍然失败,就会升级为重量级锁。在这个阶段,线程会进入阻塞状态,并通过操作系统的调度来实现锁的竞争和释放。重量级锁的性能较低,因为涉及到内核态和用户态之间的切换。


面试官: 非常清晰的解释!接下来,我们来谈谈 ReentrantLock。除了 synchronized,ReentrantLock 也是一种常用的锁。你能给我介绍一下 ReentrantLock 的特点吗?


派大星: 当然!ReentrantLock 相比于 synchronized 提供了一些额外的特性。

首先,它需要手动调用 lock()方法来获取锁,并且需要在合适的地方调用 unlock()方法来释放锁。这样的控制方式更加灵活。

其次,ReentrantLock 支持公平性,可以通过构造函数的参数来指定是否使用公平锁。公平锁会按照线程的请求顺序来分配锁,而非公平锁则允许新的线程插队获取锁,可能导致已经在等待的线程饥饿。

另外,ReentrantLock 底层使用了 CAS(Compare and Swap)操作来实现锁的获取和释放。CAS 是一种无锁算法,它利用硬件提供的原子性操作来避免使用锁,从而提高并发性能。


面试官: 很好!那么,你能跟我谈一谈 synchronized 和 ReentrantLock 在使用效率上有什么不同吗?


派大星: 在使用效率方面,ReentrantLock 通常比 synchronized 具有更好的性能。因为 synchronized 是在 JVM 层面实现的,涉及到操作系统的调度和切换,而 ReentrantLock 底层使用了 CAS 操作,减少了对操作系统的依赖,避免了线程的阻塞和切换,从而提高了并发性能。

另外,ReentrantLock 还提供了一些高级功能,比如可中断的锁和超时获取锁。这些功能在某些场景下非常有用。

然而,需要注意的是,ReentrantLock 的代码比 synchronized 更加复杂,需要手动管理锁的获取和释放。这在编码上增加了一些复杂性,并且需要注意避免死锁等问题。


面试官: 很棒的解释!最后一个问题,根据你的经验,你会在什么情况下选择使用 synchronized,而在什么情况下选择使用 ReentrantLock 呢?


派大星: 在大多数情况下,我会推荐使用 synchronized,因为它更简单、更易于使用,并且在 Java 的底层已经对其进行了优化。只有在需要更细粒度的控制或者一些高级功能时,才会考虑使用 ReentrantLock。

比如,在需要实现可中断锁或超时获取锁的场景下,可以选择 ReentrantLock。另外,如果对公平性有较高的要求,或者需要手动管理锁的获取和释放的情况下,也可以选择 ReentrantLock。

总的来说,根据具体的需求和场景,选择适合的锁机制是很重要的。

面试官: 非常好!你对 synchronized 和 ReentrantLock 的区别以及在使用层面的思考都很出色。非常感谢你的回答!


派大星: 非常感谢!我很高兴能够参与这次面试并分享我的知识。如果有任何其他问题,请随时提问!


如有问题,欢迎加微信交流:w714771310,或关注微信公众号【码上遇见你】。

发布于: 刚刚阅读数: 4
用户头像

派大星

关注

微信搜索【码上遇见你】,获取更多精彩内容 2021-12-13 加入

微信搜索【码上遇见你】,获取更多精彩内容

评论

发布
暂无评论
对线面试官-Sychronized和ReentrantLock_Java 面试题_派大星_InfoQ写作社区