目录
简述 synchronized 和 ReentrantLock 之间的区别
介绍ReentrantLock
ReentrantLock是Java中的一个可重入锁,它实现了Lock接口,并提供了一种比传统synchronized关键字更强大、更灵活的锁机制。
ReentrantLock的实现原理主要基于AQS(AbstractQueuedSynchronizer)和volatile+CAS(Compare and Swap)机制。AQS提供了一个FIFO的队列,用于构建锁的基础框架,内部通过原子变量state来表示锁的状态。volatile和CAS则用于保证多线程环境下对共享数据的原子性读写。
ReentrantLock的主要特性包括:
- 可重入性:ReentrantLock是一种特殊的互斥锁,它允许同一个线程在持有锁的情况下再次获取该锁。也就是说,同一个线程可以多次获取同一个ReentrantLock,而不会发生死锁。
- 公平性:ReentrantLock提供了公平锁和非公平锁的选择。公平锁意味着等待时间最长的线程将优先获得锁,而非公平锁则允许插队现象。然而,公平锁通常效率较低,因为需要维护一个等待队列。
- 中断响应:支持中断等待锁的线程。如果一个线程在等待锁的过程中被中断,它可以选择放弃获取锁并响应中断。
- 超时获取:ReentrantLock支持尝试获取锁的操作,并可以在等待一定时间后放弃获取锁。
- 绑定多个条件:ReentrantLock可以绑定多个Condition对象,以便在等待某个条件满足时释放锁,并在条件满足时重新获取锁。
注:
- AQS:是一个用于构建锁和同步器的框架,通过一个FIFO(先进先出)的队列来管理等待线程,实现对共享资源的访问控制
- volatile:java提供的关键字,保证修饰的变量的内存可见性和禁止指令重排序
- CAS:一种提供原子操作的同步机制,一条CPU指令实现对共享资源的原子性的读写
简述 synchronized 和 ReentrantLock 之间的区别
相同点:
- synchronized 和 ReentrantLock 都是 Java 中提供的可重入锁
不同点:
- 用法不同:synchronized 可以用来修饰普通方法、静态方法和代码块;ReentrantLock 只能用于代码块;
- 获取和释放锁的机制不同:进入synchronized 块自动加锁和执行完后自动释放锁; ReentrantLock 需要显示的手动加锁和释放锁;
- 锁类型不同:synchronized 是非公平锁; ReentrantLock 默认为非公平锁,也可以手动指定为公平锁;
- 响应中断不同:synchronized 不能响应中断;ReentrantLock 可以响应中断,可用于解决死锁的问题;
- 底层实现不同:synchronized 是 JVM 层面通过监视器实现的;ReentrantLock 是基于 AQS 实现的。