面试题答案
一键面试1. 使用 synchronized
关键字
- 原理:
synchronized
关键字通过监视器锁(monitor)来实现同步。当一个线程进入同步块时,它会获取监视器锁,其他线程就无法进入该同步块,直到持有锁的线程释放锁。这保证了同一时间只有一个线程能执行同步块中的代码,从而实现原子性操作。 - 适用场景:适用于对代码块或方法进行同步控制,确保多个线程对共享资源的访问是线程安全的。常用于对临界区代码的保护,例如对共享变量的读写操作。
2. 使用 java.util.concurrent.atomic
包下的原子类
- 原理:这些原子类利用了硬件级别的原子操作指令(如
CAS
- Compare and Swap)。以AtomicInteger
为例,它通过Unsafe
类提供的底层操作来实现原子性。CAS
操作包含三个操作数:内存位置(V)、预期原值(A)和新值(B)。只有当内存位置的值与预期原值相匹配时,才会将该位置的值更新为新值,否则不执行任何操作,并返回当前实际值。这种操作是原子的,因为它在硬件层面保证了在执行期间不会被其他线程干扰。 - 适用场景:适用于对单个变量进行原子性操作的场景,比如计数器、状态标识等。相比
synchronized
,原子类在高并发下具有更好的性能,因为它避免了锁竞争带来的开销。
3. 使用 Lock
接口及其实现类(如 ReentrantLock
)
- 原理:
Lock
接口提供了比synchronized
更灵活的同步控制。ReentrantLock
内部通过 AQS(AbstractQueuedSynchronizer)框架来实现锁的获取与释放。线程获取锁时,如果锁可用,则获取成功并将锁的持有计数加 1;如果锁不可用,则线程会被放入等待队列。当持有锁的线程释放锁时,将持有计数减 1,当计数为 0 时,锁变为可用,等待队列中的线程可以竞争获取锁。 - 适用场景:适用于需要更细粒度的锁控制,例如需要实现公平锁(
ReentrantLock
可以通过构造函数参数设置为公平锁)、可中断的锁获取、锁的条件变量等场景。相比synchronized
,Lock
提供了更多的功能,但使用起来也更加复杂。