ReentrantLock基于volatile state建立的

2019-07-15  本文已影响0人  王侦

以非公平锁为例。

1.加锁

    public void lock() {
        sync.lock();
    }
        final void lock() {
            if (compareAndSetState(0, 1))
                setExclusiveOwnerThread(Thread.currentThread());
            else
                acquire(1);
        }
    public final void acquire(int arg) {
        if (!tryAcquire(arg) &&
            acquireQueued(addWaiter(Node.EXCLUSIVE), arg))
            selfInterrupt();
    }

其中tryAcquire(arg)调用的是NonfairSync的:

        protected final boolean tryAcquire(int acquires) {
            return nonfairTryAcquire(acquires);
        }

nonfairTryAcquire(acquires)是其父类Sync中的final方法:

        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;
        }

加锁总结如下:

2.解锁

    public void unlock() {
        sync.release(1);
    }
    public final boolean release(int arg) {
        if (tryRelease(arg)) {
            Node h = head;
            if (h != null && h.waitStatus != 0)
                unparkSuccessor(h);
            return true;
        }
        return false;
    }
        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;
        }

解锁总结:

3.volatile写-读内存语义


当第二个操作是volatile写时,不允许重排序。确保了volatile写之前的操作不会重排序到volatile写之后。
当第一个操作是volatile读时,不允许重排序。确保了volatile读之后的操作不会重排序到volatile读之前。

volatile变量的happens-before规则:

总结上面的ReentrantLock的加锁和解锁:

因此在lock期间更新的共享内容对于另一个线程而言总是可见的。

上一篇下一篇

猜你喜欢

热点阅读