ReentrantLock源码简单分析

119 阅读1分钟

ReentrantLock

该类是可重入锁,跟synchronized 具有同样的作用,比它更具有扩展性,支持条件变量

获取互斥锁的逻辑

public void lock() {
    // 调用内部类的sync 的lock方法
    sync.lock();
}

Sync内部类

abstract static class Sync extends AbstractQueuedSynchronizer {
   
    abstract void lock();

	// 非公平获取互斥锁    
    final boolean nonfairTryAcquire(int acquires) {
        final Thread current = Thread.currentThread();
        int c = getState();
        // 如果没有其它线程获取锁
        if (c == 0) {
            // cas 原子性修改状态,如果是公平锁需要判断AQS排队队列中是否又等待的节点
            if (compareAndSetState(0, acquires)) {
                // 如果获取锁成功,就设置当前线程为互斥锁拥有者
                setExclusiveOwnerThread(current);
                return true;
            }
        }
        // 判断当前互斥锁的拥有者是否为当前线程,如果是当前线程,ReentranLock支持锁重入
        else if (current == getExclusiveOwnerThread()) {
            int nextc = c + acquires;
            if (nextc < 0) // overflow
                throw new Error("Maximum lock count exceeded");
            setState(nextc);
            return true;
        }
        return false;
    }

  
    final ConditionObject newCondition() {
        return new ConditionObject();
    }
}

FairSync 公平同步器

static final class FairSync extends Sync {
    final void lock() {
        // 调用AQS的 acquire方法
        acquire(1);
    }

  	// 公平获取互斥锁的版本
    protected final boolean tryAcquire(int acquires) {
        final Thread current = Thread.currentThread();
        int c = getState();
        if (c == 0) {
            if (!hasQueuedPredecessors() && // 没有排队节点
                compareAndSetState(0, acquires)// cas 更新状态
               ) {
                // 获取锁成功,设置互斥锁拥有者
                setExclusiveOwnerThread(current);
                return true;
            }
        }
        // 锁重入处理
        else if (current == getExclusiveOwnerThread()) {
            int nextc = c + acquires;
            // 负数就是溢出了
            if (nextc < 0)
                throw new Error("Maximum lock count exceeded");
            setState(nextc);
            return true;
        }
        return false;
    }
}

NonfairSync 非公平同步器

static final class NonfairSync extends Sync {
   	
    final void lock() {
        // 直接CAS ,这就是非公平锁
        if (compareAndSetState(0, 1))
            //获取锁成功
            setExclusiveOwnerThread(Thread.currentThread());
        else
            // 调用AQS
            acquire(1);
    }

    protected final boolean tryAcquire(int acquires) {
        // 调用Sync内部类的非公平锁的实现
        return nonfairTryAcquire(acquires);
    }
}

小总结:FairSync VS NonfairSync

公平锁和非公平锁的区别在于需不需要判断AQS排队队列中是否有元素,非公平锁的直接进行CAS 修改状态,不判断队列中是否有元素,默认实现都是非公平的,因为进出队列需要花费一定的时间,线程等待和唤醒需要保存和恢复线程上下文页需要时间,CPU调度也需要一定的时间,所以非公平比公平锁性能更高

释放互斥锁逻辑--unlock

// 释放共享锁
public void unlock() {
    // 调用AQS的 release方法,会调用子类的tryRelease方法
    sync.release(1);
}

Sync类的 tryRelease

// 释放锁,
protected final boolean tryRelease(int releases) {
    int c = getState() - releases;
    // 没有获取锁释放锁,就会报IllegalMonitorStateException 这个错误,就像在不加synchronized 调用wait()和notiyfy()方法一样
    if (Thread.currentThread() != getExclusiveOwnerThread())
        throw new IllegalMonitorStateException();
    boolean free = false;
    // 互斥锁释放完成
    if (c == 0) {
        free = true;
        // 清空互斥锁的线程拥有者
        setExclusiveOwnerThread(null);
    }
    // 设置状态,该操作线程安全,只有获取锁才能调用该方法
    setState(c);
    return free;
}

总结:

ReentranLock使用AQS的state来判断是否已经上锁,如果state>0表示该锁已经有线程获取锁了,state的数量代表重入锁的次数