您的当前位置:首页正文

ReentrantLock解析

来源:花图问答

ReentrantLock内部持有Sync对象,继承了AQS(AbstractQueuedSynchronizer)抽象类

public class ReentrantLock implements Lock, java.io.Serializable {
    private static final long serialVersionUID = 7373984872572414699L;
    /** Synchronizer providing all implementation mechanics */
    private final Sync sync;

    /**
     * Base of synchronization control for this lock. Subclassed
     * into fair and nonfair versions below. Uses AQS state to
     * represent the number of holds on the lock.
     */
    abstract static class Sync extends AbstractQueuedSynchronizer {
        private static final long serialVersionUID = -5179523762034025860L;

Sync有两个子类,公平和非公平


image.png
static final class FairSync extends Sync {
        private static final long serialVersionUID = -3000897897090466540L;

        final void lock() {
            acquire(1);      
        }

        /**
         * Fair version of tryAcquire.  Don't grant access unless
         * recursive call or no waiters or is first.
         */
        protected final boolean tryAcquire(int acquires) {
            final Thread current = Thread.currentThread();
            int c = getState();
            if (c == 0) {       // 说明锁未被占用
                if (!hasQueuedPredecessors() &&           // 等待队列前面没有等着的
                    compareAndSetState(0, acquires)) {     // cas更新状态 acquires == 1
                    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;
        }
    }

非公平锁的实现基本一致,只是不会判断队列里是否有等着的

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

        /**
         * Performs lock.  Try immediate barge, backing up to normal
         * acquire on failure.
         */
        final void lock() {
            if (compareAndSetState(0, 1))            // 直接cas 并保存当前线程
                setExclusiveOwnerThread(Thread.currentThread());
            else
                acquire(1);                                     // cas失败则走nonfairTryAcquire()
        }

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

// 和公平锁的唯一区别没有判断队列   !hasQueuedPredecessors() 
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;
        }