本文详细解析了Java并发包中的ReentrantLock类源代码,探讨其工作原理,并重点分析了公平锁和非公平锁的区别及应用场景。
ReentrantLock 是一种可重复进入的锁机制,实现了 Java 的 Lock 接口,并支持对共享资源进行多次锁定而不会被阻塞。这种重入性是通过继承 AbstractQueuedSynchronizer (AQS) 来实现的。
在 ReentrantLock 中有三个内部类:Sync、NonfairSync 和 FairSync。其中 Sync 是一个抽象类,实现了 AQS 的一部分方法;NonfairSync 继承了 Sync 类,并主要用于非公平锁的操作;FairSync 同样继承自 Sync 类,但用于处理公平锁的获取。
ReentrantLock 内部有一个名为 sync 的属性,在构造函数中初始化。这个属性决定了在实例化 ReentrantLock 时采用的是公平模式还是非公平模式来获取锁。默认情况下,如果使用无参数的构造方法,则会创建一个非公平锁;而通过带参的构造方法可以指定具体需要哪种类型的锁。
ReentrantLock 提供了多个重要方法:lock()、lockInterruptibly()、tryLock() 以及 tryLock(long time, TimeUnit unit) 等用于获取和释放锁,还有 newCondition() 方法用来创建条件变量。在 lock() 方法中,实际调用的是 sync 对象的 lock() 方法;如果需要公平锁,则会使用 FairSync 类中的实现方式;反之则采用 NonfairSync 的方法来执行。
ReentrantLock 支持两种主要模式:公平和非公平。其中,“公平”意味着当多个线程请求同一把锁时,将按照它们提出请求的顺序进行分配;而非公平机制允许新来的线程插队获取到锁资源而不需要等待前面的所有者释放它。默认情况下 ReentrantLock 使用的是非公平策略。
由于实现了可重入性,一个已经持有某对象上的 ReentrantLock 的线程可以再次尝试锁定该对象,并且会成功获得更多的递归级别而不受阻塞影响。这种特性使得在编写复杂的同步代码时非常有用和方便。
总体来说,ReentrantLock 提供了比 Java 内置的 synchronized 关键字更为灵活、强大的锁管理功能,在需要更细粒度控制场景下具有广泛应用价值。