偶然看到了一篇 ReentrantLock 的源码分析文章,自己便去学习了一下源码。核心思想是如果被请求的共享资源空闲,那么就将当前请求资源的线程设置为有效的工作线程,将共享资源设置为锁定状态;如果共享资源被占用,就需要一定的阻塞等待唤醒机制来保证锁分配。
问题ReentrantLock 的 lock 方法在入队之前直接获取锁,是否冗余设计,存在冗余的代码执行?
我的观点进行了冗余设计,理解如下。
jdk8lock 简化代码如下,我的观点是:非公平锁(NofairSync) lock 方法,有两次尝试直接获取锁,是否冗余设计了?
static final class NonfairSync extends Sync { final void lock() { // 直接尝试获取锁,不公平表现 if (compareAndSetState(0, 1)) setExclusiveOwnerThread(Thread.currentThread()); else acquire(1); // acquire 方法中首先会调用 tryAcquire ,会第二次尝试获取锁 } protected final boolean tryAcquire(int acquires) { // 如果资源空闲,直接尝试获取锁 // 如果资源不空闲,判断是否当前线程占有,进行重入锁 }}static final class FairSync extends Sync { final void lock() { acquire(1); } protected final boolean tryAcquire(int acquires) { // 如果资源空闲,判断是否已经入队,进行公平处理 // 如果资源不空闲,判断是否当前线程占有,进行重入锁 }}class AbstractQueuedSynchronizer { public final void acquire(int arg) { if (!tryAcquire(arg) && acquireQueued(addWaiter(Node.EXCLUSIVE), arg)) selfInterrupt(); }}
jdk17lock 简化代码如下,我的观点是:lock 方法,有两次尝试直接获取锁,是否冗余设计了?对于公平锁,均会判断当前线程是否已经入队,是冗余的尝试;对于非公平锁,连续两次尝试直接获取锁,也是冗余的尝试
abstract static class Sync extends AbstractQueuedSynchronizer { abstract boolean initialTryLock(); final void lock() { if (!initialTryLock()) // 首次尝试获取锁 acquire(1); // acquire 方法中首先会调用 tryAcquire ,会第二次尝试获取锁 }}static final class NonfairSync extends Sync { final boolean initialTryLock() { // 如果资源空闲,直接尝试获取锁 // 如果资源不空闲,判断是否当前线程占有,进行重入锁 } protected final boolean tryAcquire(int acquires) { // 如果资源空闲,直接尝试获取锁 }}static final class FairSync extends Sync { final boolean initialTryLock() { // 如果资源空闲,判断是否已经入队,进行公平处理 // 如果资源不空闲,判断是否当前线程占有,进行重入锁 } protected final boolean tryAcquire(int acquires) { // 如果资源空闲,判断是否已经入队,进行公平处理 }}
我认为的不冗余的方式static class Sync extends AbstractQueuedSynchronizer { final void lock() { acquire(1); }}static final class NonfairSync extends Sync { protected final boolean tryAcquire(int acquires) { // 如果资源空闲,直接尝试获取锁 // 如果资源不空闲,判断是否当前线程占有,进行重入锁 }}static final class FairSync extends Sync { protected final boolean tryAcquire(int acquires) { // 如果资源空闲,判断是否已经入队,进行公平处理 // 如果资源不空闲,判断是否当前线程占有,进行重入锁 }}