Java ReentrantLock深度解析:公平锁与非公平锁机制

5星 · 超过95%的资源 3 下载量 155 浏览量 更新于2024-09-01 收藏 108KB PDF 举报
"ReentrantLock源码详解--公平锁、非公平锁" ReentrantLock是Java并发编程中非常重要的一个工具,它实现了Lock接口,并且提供了比synchronized更丰富的锁控制能力。重入锁允许一个线程多次获取同一锁,避免死锁的发生,因为线程在释放锁之前可以再次获得锁,从而能够完成复杂的数据操作。 ### 1. 重入锁的概念 重入锁,顾名思义,就是可以重新进入的锁。当一个线程已经持有某个锁,而这个锁又是重入锁时,它可以在不被阻塞的情况下继续获取该锁。这是通过在每个锁关联一个持有计数来实现的,每次获取锁时计数加一,释放锁时计数减一,直到计数归零才真正释放锁。 ### 2. ReentrantLock实现重入锁 ReentrantLock的内部类Sync继承自AbstractQueuedSynchronizer(AQS),AQS是一个抽象基类,用于实现各种同步器,如锁和信号量。Sync有两个子类:NonfairSync(非公平锁)和FairSync(公平锁)。线程获取锁时,会调用Sync的acquire方法,这个方法会调用tryAcquire,尝试获取锁。在tryAcquire中,会检查当前线程是否是锁的所有者,如果是,则增加持有计数,从而实现重入。 ### 3. ReentrantLock默认为非公平模式的原因 ReentrantLock默认使用非公平模式,是因为非公平锁在性能上通常优于公平锁。非公平锁的获取策略是“先到先得”,即使线程已经在队列中等待,也可能会被新来的线程抢占锁,这样虽然可能导致饥饿现象,但总体来说,由于减少了线程间的同步开销,整体吞吐量更高。 ### 4. ReentrantLock的其他特性 - **可中断**:ReentrantLock提供了lockInterruptibly方法,使得等待锁的线程在被中断时能够立即响应,跳出等待状态,提高程序的响应性。 - **公平与非公平**:通过构造函数可以选择公平锁或非公平锁,公平锁保证线程按照等待队列的顺序获取锁,而非公平锁则没有这个保证。 - **分段锁**:ReentrantLock可以通过`ReentrantReadWriteLock`提供读写锁,读锁允许多个线程同时读取,而写锁是独占的,这样在多读少写的场景下能提高并发性能。 - **条件条件**:ReentrantLock还提供了Condition接口,可以创建多个条件变量,每个条件变量对应一个等待队列,线程可以根据不同的条件进行等待和唤醒。 ### 源码分析 - `Sync`类是ReentrantLock的核心,它是一个抽象类,定义了锁的核心逻辑。 - `NonfairSync`实现了非公平锁,它的tryAcquire方法直接尝试获取锁,不考虑线程等待队列的状态。 - `FairSync`实现了公平锁,其tryAcquire方法会先检查是否有线程在等待,如果有,则将当前线程加入队列末尾,然后尝试获取锁。 ReentrantLock提供了更灵活的锁管理方式,不仅有重入特性,还支持公平与非公平选择、可中断锁等待以及多条件控制,是Java并发编程中不可或缺的工具。深入理解其源码有助于我们更好地利用它来设计高效、安全的多线程程序。