ReentrantLock源码解析

ReentrantLock支持公平锁和非公平锁,默认构造使用非公平锁实现。

public ReentrantLock() {
    sync = new NonfairSync();
}

public ReentrantLock(boolean fair) {
    sync = fair ? new FairSync() : new NonfairSync();
}

首先查看获取锁 lock 方法

// ReentrantLock.NonfairSync
final void lock() {
    // CAS设置同步状态state为1,成功表明获取锁成功,设置当前线程为独占锁的持有线程
    if (compareAndSetState(0, 1))
        setExclusiveOwnerThread(Thread.currentThread());
    else
        acquire(1); // CAS失败,重新尝试获取锁
}
// AbstractQueuedSynchronizer
public final void acquire(int arg) {
    if (!tryAcquire(arg) &&
        acquireQueued(addWaiter(Node.EXCLUSIVE), arg))
        selfInterrupt();
}
// ReentrantLock.NonfairSync
protected final boolean tryAcquire(int acquires) {
    return nonfairTryAcquire(acquires); // 尝试获取非公共独占锁
}
// ReentrantLock.Sync
final boolean nonfairTryAcquire(int acquires) {
    final Thread current = Thread.currentThread();
    int c = getState(); // 获取同步状态state值
    if (c == 0) { // 0代表没有被线程持有,CAS获取锁,获取成功则将当前线程设置为独占锁的持有线程
        if (compareAndSetState(0, acquires)) {
            setExclusiveOwnerThread(current);
            return true;
        }
    }
    // 当前线程与独占锁持有者线程相同
    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;
}

对于公平锁实现,仅仅在 tryAcquire 中添加判断是否有等待获取锁的线程等待时间比当前线程久。

// ReentrantLock.FairSync
protected final boolean tryAcquire(int acquires) {
    final Thread current = Thread.currentThread();
    int c = getState();
    if (c == 0) {
        // 相比非公平锁,添加判断是否有线程等待获取锁的时间比当前线程还久
        if (!hasQueuedPredecessors() &&
            compareAndSetState(0, acquires)) {
            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;
}

释放锁 unlock 方法

// ReentrantLock
public void unlock() {
    sync.release(1);
}
// AbstractQueuedSynchronizer
public final boolean release(int arg) {
    if (tryRelease(arg)) {
        Node h = head;
        if (h != null && h.waitStatus != 0)
            unparkSuccessor(h);
        return true;
    }
    return false;
}
// ReentrantLock.Sync
protected final boolean tryRelease(int releases) {
    int c = getState() - releases; // 递减锁重入次数
    // 判断当前线程是否为独占锁持有线程,否则抛出异常
    if (Thread.currentThread() != getExclusiveOwnerThread())
        throw new IllegalMonitorStateException();
    boolean free = false; // 锁释放标识
    // c等于0,说明锁已经释放,设置锁释放标识为true
    if (c == 0) { 
        free = true;
        setExclusiveOwnerThread(null); // 置空独占锁持有线程
    }
    setState(c); // 设置同步状态state
    return free; // 返回锁释放标识
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值