美文网首页
AQS源码浅析(7)——独占模式ReentrantLock

AQS源码浅析(7)——独占模式ReentrantLock

作者: 墨_0b54 | 来源:发表于2022-04-08 19:35 被阅读0次

    ReentrantLock的基本语义与synchronized相同,但相对synchronized更加灵活。
    ReentrantLock有两种模式:公平模式和非公平模式。

    ReentrantLock加锁的实现

    公平模式下,如果有线程正在等待,则不参与竞争,对AQS的tryAcquire实现如下:

    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) //溢出了,最大可重入是int的最大值
                throw new Error("Maximum lock count exceeded");
            setState(nextc);
            return true;
        }
        return false;
    }
    

    非公平模式下,直接参与竞争,对AQS的tryAcquire实现如下:

    final void lock() {//非公平,直接竞争一次
        if (compareAndSetState(0, 1))
            setExclusiveOwnerThread(Thread.currentThread());
        else
            acquire(1);
    }
    protected final boolean tryAcquire(int acquires) {
        return nonfairTryAcquire(acquires);
    }
    final boolean nonfairTryAcquire(int acquires) {
        final Thread current = Thread.currentThread();
        int c = getState();
        if (c == 0) {
            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;
    }
    

    ReentrantLock对解锁实现

    先看一下ReentrantLock的基本实现,我们仅看解锁相关方法,实现很简单易懂

    protected final boolean tryRelease(int releases) {
        int c = getState() - releases;
        if (Thread.currentThread() != getExclusiveOwnerThread())
            throw new IllegalMonitorStateException();
        boolean free = false;
        if (c == 0) {
            free = true;
            setExclusiveOwnerThread(null);
        }
        setState(c);
        return free;
    }
    

    相关文章

      网友评论

          本文标题:AQS源码浅析(7)——独占模式ReentrantLock

          本文链接:https://www.haomeiwen.com/subject/beqssrtx.html