MST

星途 面试题库

面试题:Java多线程同步中ReentrantLock与synchronized的深入对比

对比Java多线程同步机制里ReentrantLock和synchronized在功能特性、性能表现、锁的获取与释放方式、适用场景等方面的差异。如果在高并发环境下,一个业务既要保证线程安全又要实现公平锁机制,你会优先选择哪个并说明原因。
38.7万 热度难度
编程语言Java

知识考点

AI 面试

面试题答案

一键面试

功能特性

  • ReentrantLock
    • 支持公平锁和非公平锁,通过构造函数参数控制,默认非公平锁。公平锁能保证等待时间最长的线程优先获取锁,减少线程饥饿。
    • 提供了更灵活的锁获取方式,如tryLock()可尝试获取锁,获取不到立即返回;tryLock(long timeout, TimeUnit unit)可在指定时间内尝试获取锁。
    • 支持条件变量(Condition),可实现更精细的线程间协作,一个ReentrantLock可创建多个Condition实例。
  • synchronized
    • 是非公平锁,无法实现公平锁机制。
    • 锁获取方式比较单一,进入同步块或方法时获取锁,退出时释放锁。
    • 线程协作依赖wait()notify()notifyAll()方法,这些方法依赖于对象监视器,功能相对简单。

性能表现

  • ReentrantLock:在高并发且竞争激烈的场景下,非公平锁的性能通常优于synchronized,因为非公平锁减少了线程切换开销。在低竞争场景下,两者性能差异不大。
  • synchronized:在Java 6之后进行了很多优化,如偏向锁、轻量级锁等,性能有了很大提升。在竞争不激烈时,性能表现良好。

锁的获取与释放方式

  • ReentrantLock:通过lock()方法获取锁,需手动调用unlock()方法释放锁,且unlock()必须在try - finally块中调用,以确保锁能正确释放,避免死锁。
  • synchronized:进入同步代码块或方法时自动获取锁,退出同步代码块或方法时自动释放锁。

适用场景

  • ReentrantLock:适用于需要更灵活的锁控制、公平锁机制、复杂线程协作的场景,如高并发下的任务调度系统。
  • synchronized:适用于简单的线程同步场景,如方法同步、代码块同步,尤其是竞争不激烈的场景。

高并发环境下的选择

在高并发环境下,一个业务既要保证线程安全又要实现公平锁机制,优先选择ReentrantLock。原因是synchronized无法实现公平锁机制,而ReentrantLock通过构造函数设置为公平锁,能满足业务对公平性的要求,同时其灵活的锁获取方式和条件变量机制,在高并发复杂业务场景下更具优势。