ReentrantLock源码解读

时间:2019-06-12
本文章向大家介绍ReentrantLock源码解读,主要包括ReentrantLock源码解读使用实例、应用技巧、基本知识点总结和需要注意事项,具有一定的参考价值,需要的朋友可以参考一下。

在看此文章前,先要了解一下上一篇文章AbstractQueuedSynchronizer(AQS)。

ReentrantLock

ReentrantLock锁的实现分为两种(公平锁、非公平锁),默认是非公平锁。

ReentrantLock lock = new ReentrantLock();

Sync(公平锁和非公平锁都继承此抽象类)

nonfairTryAcquire(尝试获取锁)


    /**
     * @param acquires state的增加值
     */
    final boolean nonfairTryAcquire(int acquires) {
        // 获取当前线程
        final Thread current = Thread.currentThread();
        // 获取state,0为未被线程持有,大于0为已被线程持有
        int c = getState();
        if (c == 0) {
            if (compareAndSetState(0, acquires)) {
                // 设置持有的线程为当前线程
                setExclusiveOwnerThread(current);
                return true;
            }
        }
        // 【可重入】如果当前线程已经持有
        else if (current == getExclusiveOwnerThread()) {
            // 当前的state + acquires,在NonfairSync中,即当前state+1
            int nextc = c + acquires;
            if (nextc < 0) // overflow
                throw new Error("Maximum lock count exceeded");
            // 为什么这里用setState,而不是compareAndSetState,因为当前线程已经持有,setState不会造成其他冲突
            setState(nextc);
            return true;
        }
        return false;
    }

tryRelease(尝试释放锁)

        /**
         * @param releases state的增加值
         */
        protected final boolean tryRelease(int releases) {
            int c = getState() - releases;
            // 判断当前线程是否为持有锁的线程,【解铃还须系铃人】
            if (Thread.currentThread() != getExclusiveOwnerThread())
                throw new IllegalMonitorStateException();
            // 释放标识
            boolean free = false;
            // 当state为0的时候,才表明已经没有线程持有
            if (c == 0) {

                // 标识可以释放
                free = true;
                setExclusiveOwnerThread(null);
            }
            // 设置state
            setState(c);
            return free;
        }

NonfairSync(非公平锁)

static final class NonfairSync extends Sync {
    private static final long serialVersionUID = 7316153563782823691L;

    final void lock() {
        // 如果状态为0(没有线程占用),则设置为1,此方法在AbstractQueuedSynchronizer中
        if (compareAndSetState(0, 1))
            // 设置当前持有的线程,此方法在AbstractOwnableSynchronizer中
            setExclusiveOwnerThread(Thread.currentThread());
        else
            acquire(1);
    }

    // 试图获取锁
    protected final boolean tryAcquire(int acquires) {
        return nonfairTryAcquire(acquires);
    }
}

FairSync(公平锁)

unlock

    public void unlock() {
        sync.release(1);
    }

原文地址:https://www.cnblogs.com/jarjune/p/11011302.html