interview
java-concurrency
Synchronized 和 ReentrantLock 有什么区别

Java 并发面试题, Synchronized 和 ReentrantLock 有什么区别?

Java 并发面试题, Synchronized 和 ReentrantLock 有什么区别?

QA

Step 1

Q:: Synchronized 和 ReentrantLock 有什么区别?

A:: Synchronized 是 Java 的关键字,用于实现同步,保证同一时间只有一个线程访问同步代码块。ReentrantLock 是 java.util.concurrent 包中的类,提供了更高级的锁功能,如可以尝试获得锁、超时获得锁和中断获取锁。Synchronized 是 JVM 层面实现的,ReentrantLock 是 Java 层面实现的。Synchronized 无法手动释放,ReentrantLock 需要手动释放。

Step 2

Q:: Synchronized 和 ReentrantLock 在性能上有什么差异?

A:: 在低竞争的情况下,Synchronized 的性能通常比 ReentrantLock 更好,因为 JVM 能对 Synchronized 进行许多优化。在高竞争的情况下,ReentrantLock 由于其提供的更多灵活性(如公平锁机制)可能表现更好。

Step 3

Q:: 如何选择使用 Synchronized 还是 ReentrantLock?

A:: 如果需要简单的同步机制并且锁竞争不高,使用 Synchronized 会更简洁和高效。如果需要更多的控制和灵活性,比如公平锁、超时尝试获取锁、可以中断获取锁等,应该使用 ReentrantLock。

Step 4

Q:: ReentrantLock 提供了哪些 Synchronized 不具备的功能?

A:: ReentrantLock 提供了更高的灵活性,包括:公平锁选择、可以尝试获取锁、可以中断获取锁、可以在指定时间内尝试获取锁、Condition 机制以实现多条件等待/通知模型。

Step 5

Q:: 什么是公平锁和非公平锁?

A:: 公平锁是指线程按照请求锁的顺序依次获得锁,防止线程饥饿。非公平锁则允许后来的线程插队,有可能使某些线程长时间无法获得锁。ReentrantLock 可以设置为公平锁或非公平锁,默认是非公平锁。

用途

Java 并发编程是高并发环境中保证线程安全和高效运行的重要内容。在多线程环境下,合理使用锁机制(如 Synchronized 和 ReentrantLock)可以防止数据竞争和死锁,确保系统稳定性和性能。因此,面试中考察 Synchronized 和 ReentrantLock 的理解和使用非常重要。\n

相关问题

🦆
什么是线程安全?如何实现线程安全?

线程安全指多个线程同时访问某一代码段时,不会因为线程调度导致不确定结果。实现线程安全的方法有:使用 synchronized 关键字、使用显式锁(如 ReentrantLock)、使用线程安全的数据结构(如 ConcurrentHashMap)、使用原子类(如 AtomicInteger)。

🦆
什么是死锁?如何避免死锁?

死锁是指两个或多个线程互相等待对方释放资源,导致所有线程都无法继续执行。避免死锁的方法有:资源的有序分配、避免一个线程同时持有多个锁、使用 tryLock 尝试获取锁而不是无限等待、设置锁获取的超时时间。

🦆
什么是乐观锁和悲观锁?

乐观锁假设并发冲突不会发生,只在提交操作时检查冲突,典型实现是 CAS(Compare and Swap)。悲观锁假设并发冲突会发生,必须在操作之前加锁。乐观锁适用于读多写少的场景,悲观锁适用于写多的场景。

🦆
什么是读写锁?什么时候使用读写锁?

读写锁(ReadWriteLock)允许多个线程同时读操作,但写操作是独占的。适用于读多写少的场景,可以提高并发性能。Java 提供了 ReadWriteLock 接口及其实现类 ReentrantReadWriteLock。

🦆
什么是线程池?为什么要使用线程池?

线程池管理一组工作线程,用于执行任务,减少了线程创建和销毁的开销,提高了系统的响应速度和资源利用率。使用线程池可以限制并管理系统的并发数,避免过多线程导致的资源耗尽问题。Java 提供了 Executor 框架来管理线程池。